Copilot Chat forked session posts tool-use events with the original sessionId
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
# Copilot Chat forked session posts tool-use events with the original sessionId
## Summary
When I fork a Copilot Chat session and then trigger a tool call from the fork, the hook payload still appears to carry the original session ID instead of the forked session ID.
## Expected behavior
The forked session should emit tool-use events with its own session ID.
## Actual behavior
The hook payload seems to keep the original session ID after the fork. In my reproduction, the log entries associated with the tool call show the same session ID as the original session, not the forked one.
## Repro steps
1. Start a new Copilot Chat session in VS Code.
2. In the original session, ask Copilot to create `test-bug.txt`. This produced the `PostToolUse` payload at 2026-09-07T08:27:17.009Z.
3. Fork that session and switch to the fork.
4. In the forked session, ask Copilot to create `second_reproduction_note.txt`. This produced the `PostToolUse` payload at 2026-09-07T08:36:23.049Z.
5. Compare the persisted UI session records with the matching `PostToolUse` entries, using `toolCallId`/`tool_use_id` as the correlation key.
## Evidence from logs
All files below are written by VS Code or GitHub Copilot Chat. The attached excerpts contain complete, unmodified source lines: no fields or paths were redacted, normalized, or reconstructed. No custom hook state is used as evidence.
### 1. The UI records two different chat sessions
Original UI session file:
`~/Library/Application Support/Code/User/workspaceStorage/a4f25f2e4c76b5d1dca53654accf13a9/chatSessions/2ddd5b6e-81b7-441c-a97c-f580723002cb.jsonl`
Its initial record contains:
```json
{"sessionId":"2ddd5b6e-81b7-441c-a97c-f580723002cb","customTitle":"Bug reproduction in Copilot"}
```
The session records tool call `call_kkK1DAtJ8y61Ials8ZecgKqb` as `copilot_createFile`, with the completed invocation message identifying `/Users/rogzhang93/DSR-SQL/test-bug.txt`.
Forked UI session file:
`~/Library/Application Support/Code/User/workspaceStorage/a4f25f2e4c76b5d1dca53654accf13a9/chatSessions/e14064d7-f8d4-48ef-9185-c92fd0cfba1a.jsonl`
Its initial record contains:
```json
{"sessionId":"e14064d7-f8d4-48ef-9185-c92fd0cfba1a","customTitle":"Forked: Bug reproduction in Copilot"}
```
The forked session records both of these completed tool invocations:
```text
call_iWeIUVS6fDPSYzbbMxus5onN -> /Users/rogzhang93/DSR-SQL/scripts/tmp/copilot-hooks/second_reproduction_note.txt
call_6RiouNRBi8P8EDLihDKHxxRN -> /Users/rogzhang93/DSR-SQL/root_note.txt
```
The same forked UI session file stores `metadata.sessionId=2ddd5b6e-81b7-441c-a97c-f580723002cb` in the request results associated with both fork-only tool calls. This differs from the file's own top-level UI `sessionId=e14064d7-f8d4-48ef-9185-c92fd0cfba1a`.
### 2. The hook payload uses the original session ID for both UI sessions
Hooks log:
`~/Library/Application Support/Code/logs/20260904T095751/window4/exthost/GitHub.copilot-chat/GitHub Copilot Chat Hooks.log`
Line 4715 starts the original session with `source":"new"`:
```text
2026-09-07 16:25:58.997 [info] [#940] [SessionStart] Input: {"timestamp":"2026-09-07T08:25:58.997Z","hook_event_name":"SessionStart","session_id":"2ddd5b6e-81b7-441c-a97c-f580723002cb","transcript_path":"/Users/rogzhang93/Library/Application Support/Code/User/workspaceStorage/a4f25f2e4c76b5d1dca53654accf13a9/GitHub.copilot-chat/transcripts/2ddd5b6e-81b7-441c-a97c-f580723002cb.jsonl","source":"new","model":"gpt-5.4-mini","cwd":"/Users/rogzhang93/DSR-SQL"}
```
Line 4730, emitted by the original session before the fork:
```text
2026-09-07 16:27:17.010 [info] [#943] [PostToolUse] Input: {"timestamp":"2026-09-07T08:27:17.009Z","hook_event_name":"PostToolUse","session_id":"2ddd5b6e-81b7-441c-a97c-f580723002cb","transcript_path":"/Users/rogzhang93/Library/Application Support/Code/User/workspaceStorage/a4f25f2e4c76b5d1dca53654accf13a9/GitHub.copilot-chat/transcripts/2ddd5b6e-81b7-441c-a97c-f580723002cb.jsonl","tool_name":"create_file","tool_input":"...","tool_response":"","tool_use_id":"call_kkK1DAtJ8y61Ials8ZecgKqb__vscode-1788498431970","cwd":"/Users/rogzhang93/DSR-SQL"}
```
Line 4740, emitted by the forked session after the fork:
```text
2026-09-07 16:36:23.050 [info] [#945] [PostToolUse] Input: {"timestamp":"2026-09-07T08:36:23.049Z","hook_event_name":"PostToolUse","session_id":"2ddd5b6e-81b7-441c-a97c-f580723002cb","transcript_path":"/Users/rogzhang93/Library/Application Support/Code/User/workspaceStorage/a4f25f2e4c76b5d1dca53654accf13a9/GitHub.copilot-chat/transcripts/2ddd5b6e-81b7-441c-a97c-f580723002cb.jsonl","tool_name":"create_file","tool_input":"...","tool_response":"","tool_use_id":"call_iWeIUVS6fDPSYzbbMxus5onN__vscode-1788498431971","cwd":"/Users/rogzhang93/DSR-SQL"}
```
`"tool_input":"..."` above is the literal content persisted by the Hooks logger; it is not an omission made while quoting the log. The complete arguments remain available in the Copilot transcript and map the same IDs to these files:
```text
call_kkK1DAtJ8y61Ials8ZecgKqb -> /Users/rogzhang93/DSR-SQL/test-bug.txt
call_iWeIUVS6fDPSYzbbMxus5onN -> /Users/rogzhang93/DSR-SQL/scripts/tmp/copilot-hooks/second_reproduction_note.txt
call_6RiouNRBi8P8EDLihDKHxxRN -> /Users/rogzhang93/DSR-SQL/root_note.txt
```
The shared `toolCallId` prefix provides the cross-file join. It proves that `call_kkK1DAtJ8y61Ials8ZecgKqb` came from UI session `2ddd5b6e-81b7-441c-a97c-f580723002cb`, while `call_iWeIUVS6fDPSYzbbMxus5onN` came from the separately persisted UI session `e14064d7-f8d4-48ef-9185-c92fd0cfba1a`. Nevertheless, both corresponding `PostToolUse` payloads use `session_id=2ddd5b6e-81b7-441c-a97c-f580723002cb` and the original transcript path.
## Why I think this is a bug
If a forked chat session gets a new session ID in Copilot, but the hook payload still uses the original one, the hook cannot distinguish the fork from the source session.
## Logs and artifacts to attach
- `bug-report/forked-session-hook-issue/original-ui-session-2ddd5b6e-excerpt.json.log` (exact source lines 1, 2, 6, and 14)
- `bug-report/forked-session-hook-issue/forked-ui-session-e14064d7-excerpt.json.log` (exact source lines 1, 5, and 15)
- `bug-report/forked-session-hook-issue/github-copilot-chat-hooks-excerpt.log` (exact source lines 4715, 4730, 4740, and 4855)
- `bug-report/forked-session-hook-issue/copilot-transcript-2ddd5b6e-tool-calls-excerpt.json.log` (exact source lines 6, 13, 20, 22, 100, and 102)
## Suggested issue title
Copilot Chat forked session reuses the original sessionId in PostToolUse payload
## Evidence package
The files under `bug-report/forked-session-hook-issue/` are direct, unmodified line excerpts from VS Code-owned logs. No fields or paths were redacted, normalized, or reconstructed. No custom hook state is included.
### Session identities
- Original UI session: `2ddd5b6e-81b7-441c-a97c-f580723002cb` (`Bug reproduction in Copilot`)
- Forked UI session: `e14064d7-f8d4-48ef-9185-c92fd0cfba1a` (`Forked: Bug reproduction in Copilot`)
### Evidence files
- `original-ui-session-2ddd5b6e-excerpt.json.log`: Exact source lines 1, 2, 6, and 14 from the original UI session log. These contain the UI session identity, prompt, request-result metadata, and completed `test-bug.txt` tool invocation.
- `forked-ui-session-e14064d7-excerpt.json.log`: Exact source lines 1, 5, and 15 from the forked UI session log. These contain the forked UI session identity, fork-only prompts, request-result metadata, and completed file-creation invocations.
- `github-copilot-chat-hooks-excerpt.log`: Exact `SessionStart` and `PostToolUse` source lines 4715, 4730, 4740, and 4855 from `GitHub Copilot Chat Hooks.log`.
- `copilot-transcript-2ddd5b6e-tool-calls-excerpt.json.log`: Exact source lines 6, 13, 20, 22, 100, and 102 from the Copilot transcript. These contain the three prompts and complete `create_file` arguments.
### Correlation
The UI session logs use `toolCallId`. The Hooks log uses the same ID with a `__vscode-` suffix as `tool_use_id`.
| UI session | Tool call | Created file | Hook session ID |
| --- | --- | --- | --- |
| `2ddd5b6e-81b7-441c-a97c-f580723002cb` | `call_kkK1DAtJ8y61Ials8ZecgKqb` | `test-bug.txt` | `2ddd5b6e-81b7-441c-a97c-f580723002cb` |
| `e14064d7-f8d4-48ef-9185-c92fd0cfba1a` | `call_iWeIUVS6fDPSYzbbMxus5onN` | `second_reproduction_note.txt` | `2ddd5b6e-81b7-441c-a97c-f580723002cb` |
| `e14064d7-f8d4-48ef-9185-c92fd0cfba1a` | `call_6RiouNRBi8P8EDLihDKHxxRN` | `root_note.txt` | `2ddd5b6e-81b7-441c-a97c-f580723002cb` |
The two fork-only calls are persisted under UI session `e14064d7-f8d4-48ef-9185-c92fd0cfba1a`, but their request-result metadata and hook payloads use original session `2ddd5b6e-81b7-441c-a97c-f580723002cb`.
[copilot-transcript-2ddd5b6e-tool-calls-excerpt.json.log](https://github.com/user-attachments/files/31908449/copilot-transcript-2ddd5b6e-tool-calls-excerpt.json.log)
[forked-ui-session-e14064d7-excerpt.json.log](https://github.com/user-attachments/files/31908448/forked-ui-session-e14064d7-excerpt.json.log)
[github-copilot-chat-hooks-excerpt.log](https://github.com/user-attachments/files/31908447/github-copilot-chat-hooks-excerpt.log)
[original-ui-session-2ddd5b6e-excerpt.json.log](https://github.com/user-attachments/files/31908450/original-ui-session-2ddd5b6e-excerpt.json.log)
Contributor guide
Assessment
This issue has not been assessed yet.