stablyai/orca · error
invalid relay hello
Error message
invalid relay hello
What it means
Thrown in connectMobileRelayForPairing's acceptRelayHello when the parsed JSON does not satisfy RelayPhoneHelloSchema. The cell sent a JSON frame that is not a valid relay-hello during the pairing dial.
Source
Thrown at mobile/src/transport/mobile-relay-physical-client.ts:129
})
.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) {
return
}
closed = true
if (intentionallyClosed) {View on GitHub (pinned to 1136503c6a)
Solutions
- Inspect parsed.error issues from a local safeParse to find the failing field.
- Handle relay-moved by re-resolving the endpoint via the resume director.
- Align client and cell versions.
- Re-derive cellUrl from a fresh pairing offer.
Defensive patterns
Strategy: try-catch
Validate before calling
import { RelayPhoneHelloSchema } from '../../../src/shared/mobile-relay-phone-protocol'
function isValidHelloJson(raw: string): boolean {
try {
return RelayPhoneHelloSchema.safeParse(JSON.parse(raw)).success
} catch {
return false
}
} Type guard
import { RelayPhoneHelloSchema, type RelayPhoneHello } from '../../../src/shared/mobile-relay-phone-protocol'
function isRelayHello(value: unknown): value is RelayPhoneHello {
return RelayPhoneHelloSchema.safeParse(value).success
} Try / catch
try {
const client = connectMobileRelayForPairing(args)
} catch (error) {
if (error instanceof Error && error.message === 'invalid relay hello') {
// re-resolve endpoint in case the cell sent relay-moved
}
} Prevention
- Keep the client schema version aligned with the relay cell build.
- Distinguish relay-moved from a malformed hello and re-resolve the endpoint for the former.
- Log parsed.error issues when diagnosing against a staging cell.
When it happens
Trigger: The cell sent a 'relay-moved' notice (host reassigned), an error object, or a hello with missing/extra fields under the .strict() schema.
Common situations: Client/cell version skew changing the hello shape; the endpoint URL reached the wrong relay service; the host was reassigned so the cell advertises relay-moved.
Related errors
- invalid relay hello
- expected plaintext relay hello
- invalid relay hello JSON
- relay_outer_${code}
- Invalid accounts snapshot from host
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/6735bce42f662c04.
Report an issue: GitHub.