Skip to content

fix(up): don't fail CI mode when log streaming can't connect - #1100

Merged
ndneighbor merged 1 commit into
masterfrom
angelo/up-ci-verdict-resilience
Aug 13, 2026
Merged

fix(up): don't fail CI mode when log streaming can't connect#1100
ndneighbor merged 1 commit into
masterfrom
angelo/up-ci-verdict-resilience

Conversation

@ndneighbor

@ndneighbor ndneighbor commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

TL;DR - Dev New holds the CLI up flow in a long session so bumping up WSS timeout.

Problem

railway up --ci reports build failure (exit 1) when the build-log WebSocket subscription can't connect — even though the deploy is running and frequently succeeds. Hit four times today by dev.new publishes (which drive up --ci inside the VM); every failed publish had a deployment that built SUCCESS server-side. One first-publish victim ended up with a healthy deploy and no domain, because the caller trusts the exit code and skipped its post-deploy steps.

The fingerprint: failures at 65.8s, 66.6s, 67.2s, 67.8s. That's exactly LOGS_RETRY_CONFIG exhausting — 12 attempts, backoff 1s ×1.5 capped at 8s sums to ~61s of sleeps plus connect overhead ≈ 66s.

Root cause: the WS upgrade request has a 1-second total timeout (DNS + TCP + TLS + 101 upgrade). On a CPU-starved machine — a loaded CI runner, or a Railway VM with a build pegging its vCPUs (the dev.new case: the coding agent was mid-build) — the handshake misses 1s on every retry, while plain HTTP POSTs (the upload itself!) succeed fine. Network was ruled out: 75ms round trip from the affected host to backboard.

Fix

  1. subscription.rs: 10s handshake budget instead of 1s.
  2. up.rs CI mode: a dead log stream is a lost picture, not a lost deploy. Instead of exit(1), fall back to polling the deployment status over plain HTTP every 5s (new DeploymentStatus query) and exit with the real verdict, mirroring the status subscription's behavior (Deploy complete / Deploy failed / Deploy crashed, same JSON shapes). The deployment-status subscription's connect failure gets the same fallback instead of ?-ing out of a deploy that's already running.

Non-CI behavior unchanged; detach unchanged.

Testing

  • cargo build + cargo test (113 passing), cargo fmt
  • Verdict-path parity checked against the existing subscription match arms (same strings, same JSON, same exit codes)

🤖 Generated with Claude Code

'railway up --ci' exits 1 when the build-log WebSocket subscription fails
to connect, reporting a build failure for deploys that are still running
and often succeed. The subscription handshake had a 1-second budget
(DNS + TCP + TLS + upgrade), which a CPU-starved machine — a loaded CI
runner, or a VM building at full tilt — misses on every one of the 12
retries; the backoff schedule sums to ~66s, matching the failures
observed in production to the second.

Two changes:
- give the WS upgrade a 10s budget instead of 1s
- in CI mode, treat a dead log stream as a lost picture, not a lost
  deploy: fall back to polling the deployment status over plain HTTP
  (which works whenever the upload could happen at all) and exit with
  the real verdict. The status subscription's connect failure gets the
  same fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ndneighbor ndneighbor added the release/minor Author minor release label Aug 13, 2026
@ndneighbor
ndneighbor merged commit 7c6e5a9 into master Aug 13, 2026
7 of 8 checks passed
@ndneighbor
ndneighbor deleted the angelo/up-ci-verdict-resilience branch August 13, 2026 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release/minor Author minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants