Trigger-fired sessions against self-hosted-runner (bridge) environment intermittently die with 404 on event/transport channel

Status Closed — duplicate
Maintainer reply None cached
Activity 3 comments · opened Jul 20, 2026 · closed Jul 24, 2026

Intermittent session-termination on self-hosted-runner ("bridge") environment

This report's text was prepared with the help of Claude (an Anthropic AI assistant), based on logs and observations from the reporter's own session. The underlying data (log excerpts, session IDs, timestamps) is real and was supplied by the reporter; the write-up, hedging, and structure were drafted and adversarially self-reviewed by Claude before the reporter filed it.

Summary

Across 4 trigger-fired session attempts against one self-hosted-runner environment (kind: bridge — the platform's own environment-kind field value, not a locally chosen name), in one sitting (~1 hour), these three distinct things happened:

  • Run 1: failed at worker registration and never started a session at all.
  • Runs 2 and 3: started, then a 404 on the session's event/transport channel ended them — Run 2 after a measured ~8 seconds; Run 3 on an unknown timeline, since we only captured its console summary line, not a full debug log.
  • Run 4: same environment, same no-tool prompt as Run 3, completed normally.

This is an n=4 sample from a single session and a single environment instance — not a measured failure rate, and not evidence of a general pattern across the trigger→bridge pathway. The one success rules out a hard, always-fails block; it does not tell us whether failures are frequent-but-random, rare, or specific to something about this environment/session that we haven't identified.

Separately: direct (non-trigger) use of the same environment was reported as reliable throughout the same day. This is anecdotal, not something we captured in a log — included for context, not as log-verified fact.

Environment

claude rc's own startup banner for this environment:

Remote Control v2.1.215
Spawn mode: worktree
Max concurrent sessions: 32
  • Environment kind: self-hosted runner (kind: bridge)
  • Platform: macOS
  • Trigger creation methods tried: (a) a Claude Code Remote MCP connector's create_trigger/fire_trigger/delete_trigger tools, and (b) the raw HTTP API (POST /v1/code/triggers, POST /v1/code/triggers/{id}/run) directly. Note this variable is confounded with others in Run 4 below — see "What this weakens."

Steps to reproduce

  1. Have an environment of kind bridge (self-hosted runner) running locally, connected via claude rc --permission-mode auto --spawn worktree.
  2. From a separate Claude session (or via the HTTP API directly), create a trigger targeting that environment's environment_id, with job_config.ccr.environment_id set and a synthetic one-shot user message as the prompt.
  3. Fire the trigger (run action / fire_trigger).
  4. Observe the claude rc terminal output, and the per-session debug log claude rc writes locally (named by session ID).

Observed behavior — 4 runs, same environment

Run 1 — registration never completes (own session ID)

claude rc terminal:

[21:01:09] Error: CCR v2 worker registration failed for session cse_01RRScd92oeHFu9dT5kE1fuT: Request failed with status code 404

The session never started; no debug log was produced for it. This is the session's own ID failing registration — the trigger fire never got a live worker. Distinct in kind from Runs 2–3 below: this 404 is on the registration endpoint, before any session existed, not on an event/transport channel of a running session.

Run 2 — registration 404 for a different, unrelated session ID, then own session starts, runs ~8s, dies shortly after Bash tool-permission classification

claude rc terminal:

[21:32:54] Error: CCR v2 worker registration failed for session cse_01EVfjiATnUBH8eei5cxAjDT: Request failed with status code 404
[21:34:09] Session started: "Session cse_01LKNtkmmhBheH78ykwY2MDN" (cse_01LKNtkmmhBheH78ykwY2MDN)
...
[21:34:17] Session failed: Process exited with error cse_01LKNtkmmhBheH78ykwY2MDN

The first 404 is for a session ID (cse_01EVfjiATnUBH8eei5cxAjDT) never referenced by our trigger fire and appearing nowhere else in our logs — a stray/stale registration attempt of unclear origin logged just before the real one. Unconfirmed whether it's related to the failure below or coincidental noise.

The [21:34:09][21:34:17] span above (both lines already quoted) is 8 seconds — that is the full basis for "~8 seconds," computed directly from these two console timestamps, not a separately-measured figure.

The debug log for the actual session (cse_01LKNtkmmhBheH78ykwY2MDN) includes, in this order (no per-line elapsed-time data available to us, order only):

[DEBUG] MCP server "claude.ai Gmail": Successfully connected (transport: claudeai-proxy) in 3ms
[DEBUG] Stream started - received first chunk
[DEBUG] [API:timing] first byte after 1983ms
[DEBUG] "Permission suggestions for Bash: [...gh --version...gh auth *...]"
[DEBUG] "[auto-mode] new action being classified: {\"Bash\":\"...command -v gh...\"}"

i.e. MCP connectors came up and the model produced a response proposing a Bash call. The last line quoted is a permission-classification event, not a confirmed tool-execution event — we have no log line showing the Bash call actually ran. Next in the log:

[WARN]  CCRClient: internal events returned 404
[WARN]  CCRClient: client events returned 404
[ERROR] CCRClient: 3 consecutive 404s — session gone, exiting

So the session's own worker registered and ran, reaching at least tool-permission classification, then a separate polling channel (CCRClient "events") started 404ing and the client self-terminated after 3 consecutive failures, concluding the server had dropped the session. What this establishes: the worker believed the session was live and functioning up to shortly before the events channel started 404ing (the log shows line order, not elapsed time between the two blocks). That specific mechanism is earned only for this run, from this log.

Run 3 — 404-flavored failure signature, prompt used zero tools

To rule out anything Bash/tool-permission-related, we fired a trigger whose prompt explicitly forbade all tool use ("answer from your own knowledge only, no Bash, no file reads"). It still failed:

[21:44:03] Session failed: RemoteIO: transport closed permanently (code 404) cse_017Xa7P4v8oXTCvPYwfYoaAH

We only captured this console summary line, not a full debug-log tail, so we cannot confirm from a log excerpt how far session startup progressed, or how long the session ran, before this failure. What we can say from the line itself, and no more: a 404 on a session-transport channel ended the session, under a different subsystem name (RemoteIO) than Run 2's (CCRClient). Whether this shares Run 2's specific mechanism (worker believing the session live, then the events channel 404ing), shares some other root cause, or is a distinct bug that happens to also surface as a 404, is unconfirmed — we did not inspect server-side code and have no log detail for this run beyond the one line above.

Run 4 — identical no-tool prompt, fired via the raw HTTP trigger API — succeeded

Same environment, same no-tool prompt as Run 3, created and fired via POST /v1/code/triggers + POST /v1/code/triggers/{id}/run directly rather than through the MCP wrapper tools. This run completed normally:

[21:56:23] Session started: "Session cse_017gRxo5DvVqaH1kYqs2d9Wf" (cse_017gRxo5DvVqaH1kYqs2d9Wf)
...
{"type":"assistant", ..., "content":[{"type":"text","text":"Paris."}], ...}
{"type":"result","subtype":"success","is_error":false, ..., "result":"Paris.", "stop_reason":"end_turn", ...}

Three things changed simultaneously between this run and Runs 1–3, so none can be isolated as causal from this data alone:

  1. Trigger creation method — raw HTTP API instead of the MCP wrapper tool.
  2. MCP connector attachment — the trigger-creation API response for this run included, verbatim: "mcp_connections":[{"name":"Gmail"},{"name":"Google_Drive"},{"name":"Claude_Code_Remote"},{"name":"Google_Calendar"}]. The MCP-tool-created triggers in Runs 1–3 instead returned the warning "this trigger stores no MCP connectors" (quoted string; we did not capture a full fenced API response for that side the way we did for Run 4, so the two sides of this comparison are not equally documented here — the connector-list content is asymmetric evidence, though the warning text itself is a direct quote).
  3. Caller machine location — by this point in our working session the calling Claude session had been moved onto the same physical machine as the bridge runner, per the surrounding work session (Runs 2–3 were fired from elsewhere). We have no log excerpt establishing this — unlike point 2 above, this is not log-verified.

We have one data point on the "succeeds" side and cannot attribute the difference to any one of these three.

What this weakens (not rules out)

Each of these is based on a single contrasting run and should be read as "weakens as the primary explanation," not "excludes":

  • Tool-permission-specific: Run 3 used zero tools and failed with the same 404-flavored signature as Run 2, which did reach tool-permission classification. Weakens (doesn't rule out) an explanation tied specifically to tool/permission handling.
  • Hard, always-fails block: Run 4 succeeded via the same general mechanism (trigger fire → bridge environment) that failed 3 times. This rules out a 100%-deterministic block, but not a high-frequency intermittent one.
  • Calling-session location: failures occurred while the caller was elsewhere; the one success we have happened after the caller was reportedly co-located with the bridge's machine — but that run also changed trigger-creation method and connector attachment at the same time, so location is confounded with those variables, not isolated, and is itself not log-verified (see Run 4 point 3 above). We cannot say location does or doesn't matter from this data.
  • Bridge/runner generally broken: direct (non-trigger) use of the same environment was reported as reliable all day. Anecdotal, not a log we captured — included for context, weight it accordingly.

What we could not determine

  • Root cause of the 404s on the CCRClient/RemoteIO event/transport channel for trigger-spawned sessions.
  • Whether Run 2's CCRClient failure and Run 3's RemoteIO failure share one root cause or are two distinct bugs that both happen to surface as a 404.
  • Whether the "stray" registration 404 for an unrelated session ID in Run 2 is connected to that run's later failure, or unrelated noise.
  • Which (if any) of the three variables that changed simultaneously in Run 4 — trigger-creation method, MCP-connector attachment, caller machine location — explains why it succeeded where Runs 1–3 didn't. Not isolated; would need controlled re-testing (vary one variable at a time) to determine.

Suggested next steps for investigation (not verified by us)

  • Server-side logs for session IDs cse_01RRScd92oeHFu9dT5kE1fuT, cse_01LKNtkmmhBheH78ykwY2MDN, cse_017Xa7P4v8oXTCvPYwfYoaAH (failed) vs cse_017gRxo5DvVqaH1kYqs2d9Wf (succeeded) would show what differs server-side around session creation / event-channel wiring for trigger-fired sessions against self-hosted-runner environments.
  • Check whether trigger-fired sessions against self-hosted-runner (bridge) environments follow a different session-registration/event-channel code path than trigger-fired sessions against Anthropic-managed cloud environments, and whether that path has a race between session creation and event-channel provisioning.
  • Check whether MCP-connector attachment on the trigger (present in Run 4, absent in Runs 1–3) has any bearing on event-channel stability — the mechanism isn't obvious, and the evidence for this difference is asymmetric (see Run 4 point 2), but it's worth ruling in or out.
  • A controlled re-test varying trigger-creation method, MCP-connector attachment, and caller location independently (one at a time) would resolve the confound noted in Run 4, if reproducible with a larger sample.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗