Skip to content

proxy-relay: RELAY_TARGET_PORTS silently drops invalid entries and reinterprets non-literals — a typo'd target list starts a healthy relay with the wrong targets #1844

Closed

Description

@dezren39

proxy-relay: RELAY_TARGET_PORTS silently drops invalid entries and reinterprets non-literals — a typo'd target list starts a healthy relay with the wrong targets

Evidence (verified this run, main 3675a470)

bin/proxy-relay.mjs:44-52 parses the target list with a forgiving filter, unlike every other port in the same file:

const TARGET_PORTS = (process.env.RELAY_TARGET_PORTS || '')
  .split(',')
  .map((s) => Number(s.trim()))
  .filter((n) => Number.isInteger(n) && n >= 1 && n <= 65535);
if (TARGET_PORTS.length === 0) { /* only the all-invalid case errors */ }
  • The listen and tunnel ports in the same file go through the strict parseProxyPort from bin/proxy-port.mjs (:39, :58), whose header (bin proxies: *_PROXY_PORT parsed with bare parseInt — invalid values crash opaquely or bind the wrong port #483) spells out why: a bare numeric coercion must fail at startup naming the variable and its value, never silently reinterpret or drop. The target list — the one that decides where traffic actually goes — is the only port input exempt from that rule.
  • A non-empty remainder masks the mistake completely: the relay starts, /health answers ok, and endpoint.json is published, all with a target set smaller (or different) from the one the operator configured.

Probe (laptop, verbatim parser)

Probe dir: ~/git/fleet/probe-2026-10-28-laneB-relayports/ — proxy-relay.mjs copied byte-identical to main (sha256 2ed8aa8dded4f041abb4157d662f5e918b7efdabeadfebe5c57236f07e6edf16), the TARGET_PORTS expression extracted verbatim and run with node probe.mjs:

input result
18745,19745 (control) [18745, 19745]
18745,19745junk [18745] — typo'd target silently gone
18745,99999 [18745] — out-of-range target silently gone
18745,19745.9 [18745] — fractional target silently gone
1e4 [10000] — scientific notation silently reinterpreted as a port
0x4a39 [19001] — hex silently reinterpreted as a port
18745,,19745 [18745, 19745] — empty segment silently gone

No case throws, warns, or names the variable/value.

Why it matters

This relay is the sandbox's only path to the laptop fleet proxies, and its whole configuration surface is these env vars. A single typo in one target (19745junk, a transposed digit making 99999, a pasted hex/scientific value) does not fail the service — it degrades it silently: the relay reports healthy, the supervisor is satisfied, and connections to the missing target fail later, elsewhere, looking like a backend outage — the exact failure shape #483's strict parsing was built to eliminate for the other ports. Partial validity is the dangerous case; the all-invalid case already errors today.

Acceptance criteria

  • Every comma segment of RELAY_TARGET_PORTS is validated with the strict rule from bin/proxy-port.mjs (exactly an integer 1–65535, decimal digits only — e.g. via parseProxyPortValue per segment, or an equivalent strict helper): any invalid segment exits at startup naming RELAY_TARGET_PORTS and the offending value.
  • Empty segments (18745,,19745, a trailing comma) get one pinned behaviour — refused at startup or explicitly documented as ignored — and a test pins whichever is chosen.
  • The all-invalid / unset cases keep failing at startup as they do today.
  • Tests in a new or existing bin/proxy-relay.test.mjs (or the parser's test file): the control list parses unchanged; each invalid class above (junk suffix, out of range, fractional, 1e4, 0x…) refuses; valid multi-target order is preserved (preferred-target order matters at :161).
  • No behaviour change for valid lists: listen/proxy port handling and the /health + forwarding paths are untouched.

Activity

  1. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/proxy-relaybin/proxy-relay.mjs sandbox-to-laptop relay
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 28, 2026
  3. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator-code-b
    • Session / ID: new-issue-creator-code-b run, 2026-10-28 16:39 CDT
    • Found via: filed this run
    • Task: Filed proxy-relay RELAY_TARGET_PORTS silent-drop/reinterpret bug, verified with a laptop probe of the verbatim parser from main 3675a47 (source sha256 2ed8aa8d…).
    • Expectation: effort/xs triage; done = every target segment strict-parsed at startup per the issue's acceptance criteria, empty-segment behaviour pinned.
    • Links: probe ~/git/fleet/probe-2026-10-28-laneB-relayports/ (laptop); body hidden_files/issue-code-relayports-body.md
  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed on Nov 1, 2026
  5. 3 remaining items

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  7. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — picked up — OpenChamber scheduled lane

  8. added
    user/reviewNeeds a user-look: Muse reviews first and handles what it can
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 1, 2026
  9. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — done / handed off — OpenChamber scheduled lane

    • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane
    • Session / ID: ses_e5e66cd4547ffeQOz5YvBjamz6; queue task 5052
    • Outcome: pr_opened; PR fix(proxy-relay): validate every RELAY_TARGET_PORTS entry #4034 is OPEN at commit f7ee7738b6be558a0b24f46829a91de8478c7a5d: fix(proxy-relay): validate every RELAY_TARGET_PORTS entry #4034
    • Verification: node --test bin/proxy-port.test.mjs passed 14/14; syntax checks and git diff --check passed. Fresh PR state is OPEN/CLEAN; the only reported check is CodeRabbit skipped/NEUTRAL, with no CI jobs pending.
    • Handoff: added user/review; removed the queue/in-progress/assigned labels. The queue task is complete; PR remains open for review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/proxy-relaybin/proxy-relay.mjs sandbox-to-laptop relayeffort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemuser/reviewNeeds a user-look: Muse reviews first and handles what it can

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions