claude-code - 💡(How to fix) Fix Remote Control: sessionTimeoutSeconds schema field is unwired (no CLI flag, no env var, no consumer) [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#60568Fetched 2026-05-20 03:55:12
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×3

In @anthropic-ai/[email protected] (also reproduced in 2.1.143), the claude remote-control Zod config schema declares an optional sessionTimeoutSeconds: number field, but it has no kebab-case CLI flag, no env-var binding, and no consumer site in the binary. Long-running Remote Control sessions therefore have no upstream-supported way to auto-close. Operators have to enforce session age-out externally.

Root Cause

In @anthropic-ai/[email protected] (also reproduced in 2.1.143), the claude remote-control Zod config schema declares an optional sessionTimeoutSeconds: number field, but it has no kebab-case CLI flag, no env-var binding, and no consumer site in the binary. Long-running Remote Control sessions therefore have no upstream-supported way to auto-close. Operators have to enforce session age-out externally.

Fix Action

Fix / Workaround

Workaround we deployed

Code Example

y.object({
  dir: y.string(),
  name: y.string().optional(),
  spawnMode: y.enum(["same-dir","worktree"]).default("same-dir"),
  capacity: y.number().int().positive().default(32),
  permissionMode: y.enum(...).optional(),
  sandbox: y.boolean().default(false),
  sessionTimeoutSeconds: y.number().int().positive().optional(),  // <-- declared here
  createSessionOnStart: y.boolean().default(false)
}).strict()

---

if(P==="--sandbox")q=!0;
else if(P==="--no-sandbox")q=!1;

---

$ claude remote-control --help
OPTIONS
  --name <name>
  --remote-control-session-name-prefix <prefix>
  --permission-mode <mode>
  --debug-file <path>
  -v, --verbose
  -h, --help
  --spawn <mode>
  --capacity <N>
  --[no-]create-session-in-dir
RAW_BUFFERClick to expand / collapse

Summary

In @anthropic-ai/[email protected] (also reproduced in 2.1.143), the claude remote-control Zod config schema declares an optional sessionTimeoutSeconds: number field, but it has no kebab-case CLI flag, no env-var binding, and no consumer site in the binary. Long-running Remote Control sessions therefore have no upstream-supported way to auto-close. Operators have to enforce session age-out externally.

Reproduction (jack-mac, macOS 26.5 build 25F71, Apple Silicon M2 Pro, claude-code 2.1.144 from npm)

1. The schema declares the field

strings -n 6 .../claude-code-darwin-arm64/claude | grep -F sessionTimeoutSeconds returns one effective definition site:

y.object({
  dir: y.string(),
  name: y.string().optional(),
  spawnMode: y.enum(["same-dir","worktree"]).default("same-dir"),
  capacity: y.number().int().positive().default(32),
  permissionMode: y.enum(...).optional(),
  sandbox: y.boolean().default(false),
  sessionTimeoutSeconds: y.number().int().positive().optional(),  // <-- declared here
  createSessionOnStart: y.boolean().default(false)
}).strict()

2. The manual CLI arg parser has no branch for it

The parser handles --help, --verbose, --sandbox, --no-sandbox, --debug-file, etc. There is no --session-timeout-seconds (or any kebab-case variant). grep -F "session-timeout" strings.txt returns zero hits.

For comparison: --sandbox is hidden from --help too, but IS wired in the parser:

if(P==="--sandbox")q=!0;
else if(P==="--no-sandbox")q=!1;

No equivalent branch exists for the timeout field.

3. No env-var binding

grep -oE "CLAUDE_REMOTE_CONTROL_[A-Z_]+" strings.txt | sort -u returns only CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX. No timeout-related env var.

4. --help doesn't mention it

$ claude remote-control --help
OPTIONS
  --name <name>
  --remote-control-session-name-prefix <prefix>
  --permission-mode <mode>
  --debug-file <path>
  -v, --verbose
  -h, --help
  --spawn <mode>
  --capacity <N>
  --[no-]create-session-in-dir

5. No consumer

grep -c sessionTimeoutSeconds strings.txt = 2, both occurrences are the schema definition (one declaration, one referenced in the same schema-builder line). There is no other site that reads the parsed value. If you compare to the other schema fields (spawnMode, capacity, etc), they all have additional read-sites in the same dump.

Real-world impact (why we noticed)

A Remote Control session was wedged on jack-mac for 50+ minutes after a Bash-tool pipe deadlock (the claude.exe parent stopped draining the child shell's pipe, the child blocked on write() against a full 64 KB pipe buffer). Anthropic's relay surfaced "stopped responding mid-turn" to the Claude mobile app.

While investigating, we found a second session that had been alive for 25+ hours and which we expected the bridge to have aged out automatically. It hadn't. That's what led to verifying the schema field is unwired.

Capacity: N/32 slowly drifts up over a bridge's uptime as idle sessions accumulate, until either:

  • A wedged session triggers a relay-reconnect loop that requires launchctl kickstart to fully recover, or
  • The operator manually kills sessions.

Workaround we deployed

External cron + script that:

  • Lists claude.exe ... --session-id cse_... processes (the per-session children).
  • Excludes the bridge process whose argv is claude remote-control --name ... --spawn same-dir (no .exe, no --session-id).
  • SIGTERMs anything with elapsed time over the threshold; SIGKILL escalation after 5 s grace.

*/15 * * * * /path/to/claude-rc-session-watchdog.sh does the job, but the bridge owning this seems like the right place for it.

Suggested fixes (any one)

  1. Wire it up. Add --session-timeout-seconds N to the arg parser, expose it in --help, and have the daemon enforce it. Matching CLAUDE_REMOTE_CONTROL_SESSION_TIMEOUT env var would be a bonus.
  2. Server-side enforcement. If the relay is supposed to enforce timeouts and tell the bridge to close, document the policy and the relay's expectations.
  3. Drop the schema field if the feature isn't shipping. Right now it parses successfully via the strict schema's optional contract, which silently swallows a config value that does nothing.
  4. At minimum, document the absence in claude remote-control --help and in the docs so operators don't have to reverse-engineer the binary to find out.

Environment

  • @anthropic-ai/claude-code: 2.1.144 (also reproduces on 2.1.143)
  • Platform binary: @anthropic-ai/[email protected], 207,919,008 bytes
  • macOS: 26.5 (build 25F71), Apple Silicon M2 Pro
  • Node: 22.22.3 via nvm
  • Bridge invocation in our LaunchAgent: claude remote-control --name jack-mac --permission-mode bypassPermissions --spawn same-dir

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Remote Control: sessionTimeoutSeconds schema field is unwired (no CLI flag, no env var, no consumer) [1 participants]