Remote Control: sessionTimeoutSeconds schema field is unwired (no CLI flag, no env var, no consumer)

Resolved 💬 1 comment Opened May 19, 2026 by Maxmayhemer Closed Jun 19, 2026

Summary

In @anthropic-ai/claude-code@2.1.144 (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/claude-code-darwin-arm64@2.1.144, 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

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗