Debugging
The AI Context module includes optional debug logging to help troubleshoot consumer routing, context selection, rendering, and scope matching issues.
Enabling debug logging
- Navigate to
/admin/config/ai/context/settings/general - Expand the Debugging section
- Check the Enable debug logging checkbox
- Save the configuration
Viewing debug logs
Debug information is written to the standard Drupal log:
- Go to Reports > Recent log messages (
/admin/reports/dblog) - Filter by type: ai_context
Or using Drush:
ddev exec drush watchdog:show --type=ai_context
What gets logged
Consumer routing (AiContextPreGenerateResponseSubscriber)
When a generic chat request matches at least one consumer type, one debug line is written with the invocation status, consumer ID (if any), selected item IDs, and request tags. Agent and assistant requests are excluded. Unrouted tags write nothing.
Statuses match AiContextInvocationResult: pushed, no_items,
push_disabled, type_disabled, stale, declined, ambiguous.
AiContextPreGenerateResponseSubscriber: Consumer routing; status=STATUS; consumer=ID; items=[IDS]; tags=[TAGS].
declined with an ai_automator tag and no ai_automator:id:{id}
tag means the automator instance could not be identified. A
temporary subscriber adds that ID when the field has exactly one
automator, or when the clicked widget action UUID maps to one
automator on a shared field. Multi-value fields post
{uuid}_{delta} for values after 0; those names still map. That
click also skips the other automators on the field when the
clicked automator is allowed to push. Missing field tags, or a
shared field with no matching widget click, still decline until
AI core emits the ID. push_disabled
means the consumer matched but automatic push is off (the Automator
default until you save an override).
Usage rows are written only for pushed. Use this log, not the Usage
tab, to see why a click produced no context.
The summary does not include task text or rendered context.
Context selection (AiContextSelector)
- Scope index prefilter counts: candidate IDs vs. published IDs for Minimal without subscriptions; for Minimal with active subscriptions, per-route candidate counts (subscription, global, entity-item, exact-match) instead, since that path queries the index directly and never loads the full published-ID catalog
- Number of published items loaded across chunks and always-include count
- Item count after priority-group merge
- One final selection summary with the consumer ID, selected item IDs, truncated item IDs, and token usage
- Warning when items are truncated due to token limits
- Warning when
TEXT_RENDEREDtext exceeds configuredmax_tokens - Relevant prefilter counts (base, situational, and subscription candidate IDs vs. published IDs)
- Warning when a selection scans more than 50 published items without a prefilter (once per consumer per request)
That last warning is expected for Broad, which always walks the full published catalog to fill leftover budget. Minimal and Relevant prefilter via the scope index and only fall back to a full scan when prefiltering is not possible — a scope plugin that cannot expand its subscribed values or enumerate its situational matches from indexed values. It is not a failure. It logs once per consumer per request, even if debug logging is off.
If the warning keeps appearing for a consumer on a large catalog, Minimal is the recommended mode: it skips the situational-match pass entirely, so it expands the fewest candidate IDs and loads the fewest entities. See Context selection for the trade-off.
The final debug summary uses this format:
AiContextSelector: Selection summary; consumer=CONSUMER; selected=[IDS]; truncated=[IDS]; tokens=USED/MAX.
It is emitted once per completed selection only when debug logging is enabled. The summary does not include task text, context content, provider responses, or IDs rejected by access checks.
See Selector pipeline events for when those overrides are allowed.
Scope scoring and hard context filtering run inside the selector via
AiContextScopeResolver but do not emit separate debug messages.
Context rendering (AiContextRenderer)
- Items skipped when the token budget is exhausted before or during rendering
Subcontext resolution (AiContextSubcontextResolver)
Conditional selection fails closed: when a decision cannot be completed, conditional children are excluded while required children remain selected. The resolver writes one privacy-safe warning with the parent Context Item ID, affected child count, and one of these reason categories:
missing_provider: no provider/model is configured, or the configured provider plugin is unavailabledecision_cap_exhausted: the per-request conditional parent limit was reachedinvalid_response: the provider response is not a JSON list of scalar child IDs. Conditional subcontext asks the model for a fenced JSON code block wrapping a JSON array of child IDs (or an empty array if none), with no text before or after the fence. A bare array such as["123"]does not decode on AI core 1.5.x, so those replies are logged with this reason and every conditional child is dropped. A fenced non-array such as"none"is also this reason, notprovider_exception.unsupported_provider: the provider does not support chatprovider_exception: provider creation or execution failed
The warning uses this format:
AiContextSubcontextResolver: Conditional children excluded; parent=PARENT; affected=COUNT; reason=REASON.
Warnings never contain Context Item content, task text, provider-response content, or exception messages. Use the parent ID to inspect configuration, then verify the provider/model, conditional parent limit, and provider logs.
Tool consumer_id inheritance (AiContextAgentToolSubscriber)
When a context tool opts in with
AiContextInheritsConsumerIdInterface and a non-empty
non-canonical consumer_id is replaced with
agent:{running agent}, one debug line is written with the
discarded value and the replacement. Omitted, empty, and
canonical values do not log. This line is always written at
debug. It is not gated by Enable debug logging. It does
not include task text or item content.
Performance considerations
Debug logging generates significant log entries and may impact performance. Only enable it when actively troubleshooting issues. Remember to disable it when you are done debugging.