Skip to content

Reaching a paired computer without ssh fails on the hosted relay #2071

Closed

Description

@santoshkumarradha

What a person meets

Two computers are paired and chats sync between them. The person wants to reach one from the other without ssh, so on the first they run:

codeaf serve

It fails in one of two ways, and neither tells the person what to do:

  • With no setting: no sync address is set up on this machine, so there is nowhere to be reachable from. But sync on this same machine is working, through the hosted relay.
  • With CODEAF_RELAY=https://codeaf.agentfield.ai/fabric (the hosted relay): Error: error code: 522, and serve exits.

codeaf chat --at <name> can't work either, because no machine can register.

The person expected that a paired machine running codeaf serve could be reached with codeaf chat --at, with nothing else to set up.

Cause: three gaps

  1. The relay client drops the relay address's path. In internal/relay/client.go, upgrade sends the request with URL{Path: path}, so the base path is lost. A relay at https://codeaf.agentfield.ai/fabric is called at https://codeaf.agentfield.ai/v1/engine, which has no route; Cloudflare answers 522. Store, directory, watch and pairing all build their addresses with wireauth.Endpoint, which keeps the base path, so they work and this doesn't.
  2. The hosted relay has no engine routes. /fabric/v1/engine and /fabric/v1/dial/<name> answer 404 {"err":"not_found"}. relay/hosted/src/front.js routes store, dir, identity, link and pair. Only the self-hosted codeaf relay serves /v1/engine. Fixing gap 1 alone turns the 522 into a 404.
  3. serve and sync find the relay in different ways. Sync uses syncsetup.Resolve (variable, saved pairing relay, hosted default). serve uses pair.Relay() (CODEAF_RELAY or v3/remote/relay) and never falls back to the hosted default. syncsetup.Relay says sync, pairing and the first-run line must not disagree about the relay. Here they do.

The raw error code: 522 is a fourth, smaller problem: a response body from an upstream proxy is printed as if it were codeaf's own sentence.

Acceptance (end to end, on the hosted relay, no settings changed)

  • Serve works out of the box. On a machine whose chats already sync, codeaf serve with no flags or variables registers through the same relay sync uses. It prints the machine's name and a pairing code, and keeps running.
  • Connecting with --at works. From a second paired computer, codeaf chat --at <name> opens a conversation that runs on the first machine. A message sent there gets a reply, and a tool call in it runs on the first machine.
  • A project path works. codeaf chat --at <name>:path/to/project works in that folder on the first machine.
  • Serve survives a dropped connection. If the network drops while serve is running, it says "lost sync — trying again" and becomes reachable again once the network is back, without being restarted.
  • The relay address's path is kept. A relay address with a path (https://host/fabric) is called at https://host/fabric/v1/engine and …/v1/dial/<name>, as every other client does. A test pins this for a base with a path and one without.
  • Sync and serve agree on the relay. codeaf serve, codeaf pair and sync resolve the same address on the same machine. A test covers the variable, the saved pairing relay and the hosted default.
  • Failures are explained. When the relay is down or doesn't offer this, serve says so in one sentence that names the relay and what to try, never a bare upstream body like error code: 522.
  • Self-hosted keeps working. A self-hosted codeaf relay still works end to end with serve and --at.

Activity

  1. added
    bugSomething the code does that it should not
    area:remote--host, relay, pairing, enginehost, attachments
    sev:seriousWrong or missing behaviour a person meets in ordinary use
    on Oct 30, 2026
  2. santoshkumarradha commented on Oct 30, 2026

    @santoshkumarradha
    MemberAuthor

    Fixed by #2073 and live on the hosted relay. Checked end to end on the hosted relay with no settings: codeaf serve registers and shows its name and code; codeaf chat --at <name> from a second computer pairs, answers, and runs its tool calls on the first machine; --at <name>:<path> works in that folder; after the serving process went silent for two minutes it registered again by itself and was reachable without a restart. A relay without machine doors or one that is down is now one sentence naming the relay, never error code: 522.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:remote--host, relay, pairing, enginehost, attachmentsbugSomething the code does that it should notsev:seriousWrong or missing behaviour a person meets in ordinary use

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions