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
- Branch on response.status: 401/403 -> token/auth issue, 404 -> unknown host, 5xx -> retry with backoff.
- For permanent rejections (4xx), fall back to a fresh pair instead of retrying the same token.
- Verify relay.directorUrl and relay.relayHostId match the assigned relay.
- 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
- Verify relay.directorUrl and relay.relayHostId are current before resolving.
- Retry only 5xx/transient statuses with exponential backoff; treat 4xx as permanent.
- Fall back to a fresh pair when the resume token is permanently rejected.
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
- relay director resolve response too large
- GitHub API ${method} ${path} failed with ${response.status}:
- ${response.error.code}: ${response.error.message}
- Azure DevOps request failed: HTTP ${response.status}
- Bitbucket request failed: HTTP ${response.status}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/5989a4ad7069c17d.
Report an issue: GitHub.