Skip to content

[Bug]: CLAUDE_CODE_CHILD_SESSION stamp variants still leak into transcripts (residual after #9961) #9155

Closed

Description

@5238717-cell

Summary

When the orca-terminal-daemon process inherits CLAUDE_CODE_CHILD_SESSION=1 (plus the sibling CLAUDECODE, CLAUDE_CODE_SESSION_ID, CLAUDE_CODE_EXECPATH, CLAUDE_CODE_ENTRYPOINT env vars) from an ancestor claude CLI process, every PTY the daemon spawns keeps propagating those vars to the child claude CLI process running inside the tab. The child claude treats itself as a "child session" of a long-dead parent and silently skips writing the primary transcript at ~/.claude/projects/<slug>/<uuid>.jsonl, while still reporting the (never-created) path to Orca via the agent hook. As a result:

  • The Orca UI shows the tab is fine (terminal replay works from terminal-history/output.log)
  • agent-hooks/last-status.json records a transcriptPath that doesn't exist on disk
  • claude -c in the same directory says "No conversation found to continue" — because none was ever written
  • Data loss is silent and permanent (the tab's conversation cannot be resumed after close)

Once the daemon is contaminated, every new tab in that daemon lifetime is affected. The contamination is sticky and only clears on a full daemon restart.

Repro

  1. Run claude in any directory (call this session A).
  2. From inside session A's Bash tool (or any child shell of it), start Orca (e.g. orca, or a shortcut launched with the polluted env).
    • Session A's process exports CLAUDECODE=1, CLAUDE_CODE_CHILD_SESSION=1, CLAUDE_CODE_SESSION_ID=<A's id>, CLAUDE_CODE_EXECPATH=<path>, CLAUDE_CODE_ENTRYPOINT=cli to any child.
    • orca-terminal-daemon forks with all of those inherited.
  3. In Orca, open a new terminal tab in a totally unrelated project directory, and let its startup command launch claude in that cwd.
  4. Chat with claude — messages exchange normally, tools work, hooks fire.
  5. Close the tab or run claude -c in the same cwd from a plain terminal → "No conversation found to continue".
  6. Inspect ~/.claude/projects/<slug-of-cwd>/ → only an empty memory/ subdir, no <uuid>.jsonl.
  7. Inspect <orca-user-data>/agent-hooks/last-status.json → the entry for that worktree has providerSession.transcriptPath pointing to a file that does not exist.

The bug reproduces reliably as long as the daemon was started from an env carrying CLAUDE_CODE_CHILD_SESSION=1. Killing the daemon (orca-terminal-daemon.exe on Windows / matching process on POSIX) and reopening Orca from a clean shell temporarily fixes it — until the next time it is launched from within a claude session.

Evidence

Environment diff between two live claude.exe processes on the same machine (read via psutil.Process(pid).environ()):

pid 22380 — claude launched inside an Orca tab (no jsonl written)

CLAUDECODE=1
CLAUDE_CODE_CHILD_SESSION=1
CLAUDE_CODE_SESSION_ID=08a1a595-d1ec-4142-9680-0eec5fc15e17
CLAUDE_CODE_EXECPATH=C:\Users\Lee\.local\bin\claude.exe
CLAUDE_CODE_ENTRYPOINT=cli
ORCA_WORKTREE_ID=…::D:/claude/xianyu-rpc/r0rpc

pid 22468 — claude launched from a plain PowerShell in the same session (jsonl 276KB, works fine)

(none of the CLAUDE_CODE_* vars above are present)

Process chain for the broken tab: claude(22380) ← powershell(4400) ← orca-terminal-daemon.exe(16460). The daemon's own env already contains the polluted vars, so the leak originates at daemon startup, not at PTY spawn time.

The "parent" session 08a1a595-… referenced in CLAUDE_CODE_SESSION_ID lives at ~/.claude/projects/C--Users-Lee/08a1a595-….jsonl, mtime frozen at a date long before the current Orca session — confirming the child is chained to a dead session, not a live one.

Orca's hook status confirms the child claude reported a transcript path that was never written:

"worktreeId": "…::D:/claude/xianyu-rpc/r0rpc",
"providerSession": {
  "id": "ae5def5f-3bdd-4138-8644-7d9411d9fca3",
  "transcriptPath": "C:\\Users\\Lee\\.claude\\projects\\D--claude-xianyu-rpc-r0rpc\\ae5def5f-….jsonl"
}

ls on that path → No such file or directory. hookEventName on the same entry is PostToolUse (so conversation definitely happened).

Root Cause

src/main/ipc/pty.ts scrubs some inherited env keys before spawning a PTY (see AGENT_HOOK_RUNTIME_ENV_KEYS around L211 and its use in buildPtyHostEnv at L941), but the Claude CLI's own contract env — the CLAUDE_CODE_* / CLAUDECODE set — is never cleaned. Searching the whole codebase for those keys turns up only a test file (src/main/runtime/claude-agent-teams-service.test.ts), i.e. they are never actively deleted from spawnEnv on any code path.

Suggested Fix

Add a new constant next to AGENT_HOOK_RUNTIME_ENV_KEYS in src/main/ipc/pty.ts:

// Why: when Orca's daemon is launched from inside a `claude` CLI session,
// it inherits these Claude-internal envs and then leaks them into every
// PTY it spawns. A child `claude` seeing CLAUDE_CODE_CHILD_SESSION=1
// treats itself as a subordinate session and does not persist its own
// transcript to ~/.claude/projects/<slug>/<uuid>.jsonl, silently making
// the conversation unresumable. Strip these before every PTY spawn so
// each tab's claude sees a clean session context.
const CLAUDE_CODE_INHERITED_ENV_KEYS = [
  'CLAUDECODE',
  'CLAUDE_CODE_CHILD_SESSION',
  'CLAUDE_CODE_SESSION_ID',
  'CLAUDE_CODE_EXECPATH',
  'CLAUDE_CODE_ENTRYPOINT'
] as const

And extend the existing scrub loop inside buildPtyHostEnv (right after the current AGENT_HOOK_RUNTIME_ENV_KEYS loop around L941):

for (const key of CLAUDE_CODE_INHERITED_ENV_KEYS) {
  delete baseEnv[key]
}

Corresponding test in src/main/ipc/pty.test.ts: assert that a baseEnv seeded with all five CLAUDE_CODE_* keys comes back with them removed after buildPtyHostEnv.

This matches the shape of the existing hook-env scrubbing pattern and is scoped to the exact daemon-inherited env that causes the bug. It also permanently prevents recurrence — even if a user relaunches Orca from a claude session tomorrow, the daemon-level pollution can no longer leak into PTYs.

Environment

  • Orca 1.4.144-rc.1 (built from main @ 64181fdd4) on Windows 11
  • Claude Code 2.1.212, Windows binary at C:\Users\Lee\.local\bin\claude.exe
  • Node 22.16, pnpm 10.24.0
  • Only tested on Windows; the same env-inheritance mechanism exists on macOS/Linux, so I expect the bug to reproduce there too, but I have not verified.

Activity

  1. lishixiang0705 commented on Jul 30, 2026

    @lishixiang0705

    Confirming this reproduces on macOS too (Orca 1.4.156, Claude Code CLI 2.1.220).

    Environment observed on a claude-spawned Bash subprocess running inside an Orca-managed terminal pane on this machine — all five keys from #10188's denylist are present:

    CLAUDECODE=1
    CLAUDE_CODE_CHILD_SESSION=1
    CLAUDE_CODE_SESSION_ID=<uuid>
    CLAUDE_CODE_EXECPATH=/Users/<user>/.local/share/claude/versions/2.1.220
    CLAUDE_CODE_ENTRYPOINT=cli
    

    Also matches the "sticky across auto-updates" behavior noted in #9961's writeup: this machine currently has three different orca-terminal-daemon protocol generations alive at the same time (v23, v26, v28), consistent with a contaminated launch surviving multiple app auto-updates without a full daemon restart.

    #9961 (merged) only strips CLAUDE_CODE_CHILD_SESSION / CLAUDE_CODE_SESSION_ID / CLAUDE_CODE_BRIDGE_SESSION_ID, so CLAUDECODE and CLAUDE_CODE_EXECPATH are still leaking through on this build. Would be good to get #10188 merged to close the remaining gap.

  2. nwparker commented on Aug 23, 2026

    @nwparker
    Contributor

    Closing because child-session stamps are stripped at spawn (PR #9961).
    Disagree? Please respond! I will re-visit this ticket in 5 days. If you respond, I will re-open it 🙏.

  3. changed the title [-]Terminal PTY inherits CLAUDE_CODE_CHILD_SESSION from an ancestor claude process; child claude tabs silently skip transcript persistence[/-] [+][Bug]: CLAUDE_CODE_CHILD_SESSION stamp variants still leak into transcripts (residual after #9961)[/+] on Aug 25, 2026
  4. nwparker commented on Aug 25, 2026

    @nwparker
    Contributor

    Re-opening — core fix landed in #9961 but residual stamp-key coverage is still open in PR #10188.

  5. added a commit that references this issue on Oct 26, 2026
    f05da69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions