stablyai/orca · error
invalid relay hello JSON
Error message
invalid relay hello JSON
What it means
Thrown in connectMobileRelayForPairing's acceptRelayHello when the first WS frame is a string but JSON.parse throws. The cell's plaintext hello is not valid JSON during the pairing dial.
Source
Thrown at mobile/src/transport/mobile-relay-physical-client.ts:125
acceptRelayHello(event.data)
return
}
await channel.handleMessage(event.data)
})
.catch((error: unknown) => fail(asError(error)))
}
socket.onerror = () => fail(new Error('relay transport error'))
socket.onclose = (event) => fail(new RelayOuterError(event.code || 1006))
function acceptRelayHello(raw: unknown): void {
if (typeof raw !== 'string') {
throw new Error('expected plaintext relay hello')
}
let value: unknown
try {
value = JSON.parse(raw)
} catch {
throw new Error('invalid relay hello JSON')
}
const parsed = RelayPhoneHelloSchema.safeParse(value)
if (!parsed.success) {
throw new Error('invalid relay hello')
}
if (!parsed.data.ok) {
throw new RelayOuterError(parsed.data.code)
}
if (parsed.data.credentialKind !== (args.expectedCredentialKind ?? 'invite')) {
throw new Error('relay credential resolved as an unexpected credential kind')
}
outerReady = true
log('info', 'Relay: cell accepted credential', 'Starting E2EE handshake')
channel.start()
}
function fail(error: Error): void {
if (closed) {View on GitHub (pinned to 1136503c6a)
Solutions
- Log the redacted raw first frame to identify the source.
- Confirm cellUrl resolves to a relay cell, not an error/landing page.
- Redial after confirming network connectivity.
- Verify cell health and version.
Defensive patterns
Strategy: try-catch
Try / catch
try {
const client = connectMobileRelayForPairing(args)
} catch (error) {
if (error instanceof Error && error.message === 'invalid relay hello JSON') {
// log redacted raw frame; verify cellUrl; redial on a clean network
}
} Prevention
- Validate relay.cellUrl is an https origin pointing at a relay cell before dialing.
- Surface connection failures with a reconnect action rather than silent retry.
- In tests, emit valid JSON relay-hello strings from createSocket mocks.
When it happens
Trigger: The cell returned an HTML error page, a plain-text error string, or a partial frame as the first message while the client dials for pairing.
Common situations: cellUrl pointing at a load-balancer/error page; a captive portal interstitial; the cell redeployed mid-dial and emitted a non-JSON banner.
Related errors
- invalid relay hello JSON
- expected plaintext relay hello
- invalid relay hello
- relay_outer_${code}
- relay credential install result does not match pairing journ
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/acc432f4511df35a.
Report an issue: GitHub.