stablyai/orca · error

relay director resolve failed (${response.status})

Error message

relay director resolve failed (${response.status})

What it means

Thrown in resolveMobileRelayEndpoint when the POST to /v1/resolve returned a non-2xx status. The resume director rejected the resolution: bad/unknown resume token, unknown relayHostId, auth failure, or a server-side error.

Source

Thrown at mobile/src/transport/mobile-relay-resume-director.ts:35

  fetchImpl?: typeof fetch
  timeoutMs?: number
}): Promise<MobileRelayEndpoint> {
  const controller = new AbortController()
  const timer = setTimeout(() => controller.abort(), args.timeoutMs ?? 5000)
  try {
    const url = new URL('/v1/resolve', args.relay.directorUrl)
    const response = await (args.fetchImpl ?? fetch)(url.toString(), {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({
        v: 1,
        relayHostId: args.relay.relayHostId,
        resumeToken: args.resumeToken
      }),
      signal: controller.signal
    })
    if (!response.ok) {
      throw new Error(`relay director resolve failed (${response.status})`)
    }
    const declaredLength = Number(response.headers.get('content-length') ?? 0)
    if (declaredLength > MAX_RESPONSE_BYTES) {
      throw new Error('relay director resolve response too large')
    }
    const raw = await response.text()
    if (new TextEncoder().encode(raw).byteLength > MAX_RESPONSE_BYTES) {
      throw new Error('relay director resolve response too large')
    }
    const resolved = ResolveResponseSchema.parse(JSON.parse(raw) as unknown)
    return {
      ...args.relay,
      cellUrl: resolved.cellUrl,
      assignmentEpoch: resolved.assignmentEpoch
    }
  } finally {
    clearTimeout(timer)
  }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Branch on response.status: 401/403 -> token/auth issue, 404 -> unknown host, 5xx -> retry with backoff.
  2. For permanent rejections (4xx), fall back to a fresh pair instead of retrying the same token.
  3. Verify relay.directorUrl and relay.relayHostId match the assigned relay.
  4. Retry with exponential backoff for 5xx/transient failures, respecting timeoutMs.
Defensive patterns

Strategy: retry

Try / catch

async function resolveWithFallback(args: Parameters<typeof resolveMobileRelayEndpoint>[0]) {
  try {
    return await resolveMobileRelayEndpoint(args)
  } catch (error) {
    const msg = error instanceof Error ? error.message : ''
    const m = msg.match(/relay director resolve failed \((\d+)\)/)
    const status = m ? Number(m[1]) : 0
    if (status >= 500) {
      // transient: retry with backoff
      return await resolveMobileRelayEndpoint(args)
    }
    if (status >= 400) {
      // permanent: fall back to a fresh pair
      throw error
    }
    throw error
  }
}

Prevention

When it happens

Trigger: Resume token invalid or expired; relayHostId unknown to the director; director returned 401/403 (auth), 404 (unknown host), or 5xx (server fault); wrong directorUrl configured.

Common situations: Resume token from an old assignment epoch; director redeployed and lost state; a stale/incorrect directorUrl in MobileRelayEndpoint; transient director outage.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/5989a4ad7069c17d. Report an issue: GitHub.