Investigate unexpected chat agent behavior by analyzing direct debug logs in JSONL files. Use when users ask why something happened, why a request was slow, why tools or subagents were used or skipped, or why instructions/skills/agents did not load.
This skill investigates and explains unexpected chat agent behavior using direct log files.
Use this skill for questions like:
Base conclusions on evidence from logs. Do not guess.
{{VSCODE_TARGET_SESSION_LOG}}Use direct debug log files written by Copilot Chat:
debug-logs/<sessionId>/
main.jsonl — always start here; primary conversation log
models.json — (optional) snapshot of available models at session start
runSubagent-<agentName>-<uuid>.jsonl — (optional) subagent's tool calls & LLM requests
searchSubagent-<uuid>.jsonl — (optional) search subagent work
title-<uuid>.jsonl — (optional, UI-only) title generation
categorization-<uuid>.jsonl — (optional, UI-only) prompt categorization
summarize-<uuid>.jsonl — (optional, UI-only) conversation summarization
Always read main.jsonl first — it has the full conversation flow. Child files only appear when those operations occurred. main.jsonl contains child_session_ref entries that link to each child file by name. Title, categorization, and summarize files are UI housekeeping and rarely relevant to troubleshooting. When investigating model availability or selection issues, read models.json — it contains the full list of models (with capabilities, billing, and limits) that were available when the session started.
Each line is a JSON object. Common fields: ts (epoch ms), dur (duration ms), sid (session ID), type, name, spanId, parentSpanId, status (ok|error), attrs (type-specific details).
{"ts":1773200251309,"dur":0,"sid":"62f52dec","type":"discovery","name":"Load Instructions","spanId":"2cb1f2f4","status":"ok","attrs":{"details":"Resolved 0 instructions in 0.0ms | folders: [/c:/Users/user/.copilot/instructions, /workspace/.github/instructions]","category":"discovery","source":"core"}}
{"ts":1773200251415,"dur":0,"sid":"62f52dec","type":"discovery","name":"Load Agents","spanId":"38a897d8","status":"ok","attrs":{"details":"Resolved 3 agents in 0.0ms | loaded: [Plan, Ask, Explore] | folders: [/workspace/.github/agents]","category":"discovery","source":"core"}}
{"ts":1773200251431,"dur":0,"sid":"62f52dec","type":"discovery","name":"Load Skills","spanId":"472eb225","status":"ok","attrs":{"details":"Resolved 6 skills in 0.0ms | loaded: [agent-customization, troubleshoot, ...]","category":"discovery","source":"core"}}
Key attrs: details (human-readable summary with folder paths, loaded items, skip reasons), category (always "discovery"), source ("core").
{"ts":1773200222647,"dur":4,"sid":"62f52dec","type":"tool_call","name":"manage_todo_list","spanId":"000000000000000b","parentSpanId":"0000000000000003","status":"ok","attrs":{"args":"{\"operation\":\"read\"}","result":"No todo list found."}}
{"ts":1773200234047,"dur":8937,"sid":"62f52dec","type":"tool_call","name":"run_in_terminal","spanId":"000000000000000d","parentSpanId":"0000000000000003","status":"error","attrs":{"args":"{\"command\":\"echo rama\"}","result":"ERROR: conpty.node missing","error":"A native exception occurred during launch"}}
Key attrs: args (JSON string of tool input), result (tool output or error text), error (present when status:"error").
{"ts":1773200231010,"dur":3001,"sid":"62f52dec","type":"llm_request","name":"chat:gpt-4o","spanId":"000000000000000c","parentSpanId":"0000000000000003","status":"ok","attrs":{"model":"gpt-4o","inputTokens":15025,"outputTokens":126,"ttft":1987}}
Key attrs: model, inputTokens, outputTokens, ttft (time to first token in ms), error (when failed).
{"ts":1773200234011,"dur":0,"sid":"62f52dec","type":"agent_response","name":"agent_response","spanId":"agent-msg-000000000000000c","parentSpanId":"0000000000000003","status":"ok","attrs":{"response":"[{\"role\":\"assistant\",\"parts\":[{\"type\":\"text\",\"content\":\"Running your command now.\"},{\"type\":\"tool_call\",\"name\":\"run_in_terminal\",\"arguments\":\"{...}\"}]}]"}}
Key attrs: response (JSON-encoded array of message parts; may be truncated).
{"ts":1773200251345,"dur":0,"sid":"62f52dec","type":"user_message","name":"user_message","spanId":"000000000000000f","status":"ok","attrs":{"content":"using subagent count .md"}}
Key attrs: content (the user's message text).
{"ts":1773200254954,"dur":7921,"sid":"62f52dec","type":"subagent","name":"Explore","spanId":"0000000000000014","parentSpanId":"0000000000000013","status":"ok","attrs":{"agentName":"Explore"}}
Key attrs: agentName, description (optional), error (when failed).
{"ts":1773200260000,"dur":0,"sid":"62f52dec","type":"generic","name":"some-event","spanId":"abc123","status":"ok","attrs":{"details":"Additional context","category":"some-category"}}
Events form a tree via spanId/parentSpanId. A typical chain:
user_message (spanId: X) — the user's turnllm_request (parentSpanId: X) — model call for that turnagent_response (parentSpanId: X) — what the model returnedtool_call (parentSpanId: X) — tool executed from the responsellm_request (parentSpanId: X) — next model call after tool resultSubagent calls create nested hierarchies: the tool_call for runSubagent (spanId: Y) becomes the parent for a child subagent span, which in turn parents its own llm_request/tool_call events.
Debug log files live outside the workspace (in user storage), so workspace-scoped search tools like grep_search cannot access them. Use the terminal instead.
Do not use grep_search for log files — it only works on workspace files.
Use run_in_terminal with grep or jq:
grep '"status":"error"' <logPath>grep '"type":"discovery"' <logPath>jq -c 'select(.dur > 5000)' <logPath>grep '"type":"tool_call"' <logPath>grep 'search_term' <logPath>tail -n 50 <logPath>jq -r '.type' <logPath> | sort | uniq -c | sort -rnjq -c '{type, name, status, dur}' <logPath>jq -c 'select(.type == "discovery")' <logPath>jq -c 'select(.type == "user_message") | .attrs.content' <logPath>Use run_in_terminal with PowerShell commands:
Select-String '"status":"error"' <logPath>Select-String '"type":"discovery"' <logPath>Select-String '"type":"tool_call"' <logPath>Select-String 'search_term' <logPath>Get-Content <logPath> -Tail 50node -e "require('fs').readFileSync('<logPath>','utf8').split('\n').filter(Boolean).map(JSON.parse).filter(e => e.dur > 5000).forEach(e => console.log(JSON.stringify(e)))"node -e "const lines=require('fs').readFileSync('<logPath>','utf8').split('\n').filter(Boolean).map(JSON.parse);const c={};lines.forEach(e=>c[e.type]=(c[e.type]||0)+1);Object.entries(c).sort((a,b)=>b[1]-a[1]).forEach(([t,n])=>console.log(n,t))"ls -lh <logPath> (or (Get-Item <logPath>).Length on Windows). If the file is large, avoid commands that load the entire file into memory (e.g. node -e with readFileSync). Prefer streaming tools like grep, jq, Select-String, tail, or head.read_file only for small targeted ranges (a few lines) once you know the line numbers. Never read entire log files.run_in_terminal with ls -lh (or dir on Windows) to locate candidate .jsonl files and check their sizes.grep/jq are not available, fall back to Select-String or node -e one-liners (only for smaller files).main.jsonl in each directory.run_in_terminal (use grep/jq on macOS/Linux, Select-String/node -e on Windows)"status":"error"dur values (> 5000)"type":"discovery""type":"tool_call""type":"llm_request"spanId / parentSpanId when needed.If you suspect network connectivity or authentication problems (e.g., repeated request timeouts, 401/403 errors, or model endpoint failures in the logs), run the VS Code command github.copilot.debug.collectDiagnostics using the run_vscode_command tool. The command returns the full diagnostics report as a string, so you can read the result directly from the tool output. The report includes:
The command also opens the report in an editor for the user to see. Use the returned string to diagnose the network issue.
When investigating issues related to a specific type of customization file (instructions, prompt files, agents, etc.) and you need more details about the expected format or behavior, load the relevant documentation page:
https://code.visualstudio.com/docs/copilot/customization/custom-instructionshttps://code.visualstudio.com/docs/copilot/customization/prompt-fileshttps://code.visualstudio.com/docs/copilot/customization/custom-agentshttps://code.visualstudio.com/docs/copilot/customization/language-modelshttps://code.visualstudio.com/docs/copilot/customization/mcp-servershttps://code.visualstudio.com/docs/copilot/customization/hookshttps://code.visualstudio.com/docs/copilot/customization/agent-pluginsUse these when you need to verify file format expectations, confirm supported fields, or help the user fix a customization file.
When your investigation yields no clear root cause or you have no specific remediation suggestions:
https://github.com/microsoft/vscode/wiki/Copilot-Issues.Your response should cover:
You do not need separate headers for each of these. For straightforward issues, a short combined explanation with a "How to fix" section is fine. Use more structure (headers, multiple sections) only when the issue is complex or involves multiple contributing factors.
main.jsonl or runSubagent-Explore-abc123.jsonl.Bad (narrates investigation, uses internal terms, pastes raw log):
I'm investigating the session debug log to confirm whether a testing skill was discovered. In the skills discovery summary, the loader reports:
skipped: testing2 (name-mismatch). The frontmatter name in SKILL.md doesn't match the folder identity.
Good (concise, user-friendly, actionable):
The "testing" skill was found but not loaded because there's a name mismatch between the folder and the skill file:
Value Folder name testingName in SKILL.md testing2These must match for the skill to load.
How to fix
Either:
- Change
name: testing2toname: testingin your SKILL.md, or- Rename the folder from
testing/totesting2/Then start a new chat session so it gets picked up.
run_in_terminal to search log files — never use grep_search (it cannot access files outside the workspace). Use grep/jq on macOS/Linux, Select-String/node -e on Windows.read_file — they can be very large. Search first, then read_file for small targeted ranges.github.copilot.debug.collectDiagnostics via the run_vscode_command tool and use the returned diagnostics string before concluding.