stablyai/orca · error
relay pairing RPC unavailable after relay path authenticatio
Error message
relay pairing RPC unavailable after relay path authentication
What it means
Thrown in runPairing after winner.client.sendRequest('pairing.provisionRelay') returned a JSON-RPC method_not_found error AND the winning candidate path was 'relay' (not 'direct'). The coordinator tolerates a missing provisionRelay on the direct path (line 224-227, for older desktops that predate relay support), but a relay-path winner that lacks provisionRelay is unrecoverable: the relay was authenticated yet the desktop cannot mint the durable relay credential, so the pairing cannot proceed to getEndpoints.
Source
Thrown at mobile/src/transport/pre-profile-pairing-coordinator.ts:223
return { hostId }
}
journal = {
...journal,
metadata: {
...journal.metadata,
winner: winner.path,
authorizationMode: winner.path === 'direct' ? 'authenticated-direct' : 'relay-basis'
}
}
await dependencies.updateJournal(journal.metadata.journalId, () => journal!.metadata)
const provision = await winner.client.sendRequest('pairing.provisionRelay', {
reqId: journal.metadata.installReqId,
newResumeTokenHash: journal.metadata.pendingResumeTokenHash
})
if (isMethodNotFound(provision)) {
if (winner.path !== 'direct') {
throw new Error('relay pairing RPC unavailable after relay path authentication')
}
await dependencies.saveHost(baseHost(offer, hostId, hostName, now))
await dependencies.clearJournal(journal.metadata.journalId)
return { hostId }
}
const installed = DeviceCredentialInstalledSchema.parse(requireSuccess(provision))
const endpoints = PairingGetEndpointsResultSchema.parse(
requireSuccess(
await winner.client.sendRequest('pairing.getEndpoints', {
installReqId: journal.metadata.installReqId
})
)
)
assertCommittedInstall(endpoints.installStatus, installed)
if (!endpoints.relay) {
throw new Error('desktop returned no relay endpoint after credential install')
}
assertActive(isDisposed)View on GitHub (pinned to 1136503c6a)
Solutions
- Upgrade the desktop Orca runtime to a version that implements 'pairing.provisionRelay' (it must ship alongside relay transport support).
- If a legacy desktop must be supported, force the direct path by ensuring the relay candidate loses the race (e.g., withhold offer.relay) so winner.path === 'direct' takes the tolerant branch at line 224.
- Verify the desktop's RPC method registry exposes 'pairing.provisionRelay' before advertising relay capability to mobile clients.
Example fix
// before — relay-capable offer sent to a desktop lacking provisionRelay
const offer = { ...base, relay: relayEndpoint }
// after — direct-only until desktop is upgraded
const offer = { ...base /* no relay */ } Defensive patterns
Strategy: validation
Validate before calling
// Before advertising relay, confirm the desktop implements provisionRelay
async function desktopSupportsProvisionRelay(client: PairingCandidateClient): Promise<boolean> {
const probe = await client.sendRequest('rpc.methods', {})
if (!probe.ok) return false
const methods = (probe.result as { methods?: string[] }).methods ?? []
return methods.includes('pairing.provisionRelay')
} Type guard
function isRelayProvisionUnavailable(error: unknown): boolean {
return error instanceof Error
&& error.message === 'relay pairing RPC unavailable after relay path authentication'
} Try / catch
try {
await runPairing(...)
} catch (error) {
if (isRelayProvisionUnavailable(error)) {
// retry without relay so the direct path takes the tolerant branch
return startPreProfilePairing({ ...args, offer: { ...args.offer, relay: undefined } })
}
throw error
} Prevention
- Keep mobile and desktop Orca versions aligned so relay transport and provisionRelay ship together.
- Capability-probe the desktop's RPC method registry before offering relay to mobile clients.
- When supporting legacy desktops, omit offer.relay so the direct-only branch is taken.
When it happens
Trigger: A relay-path winner (racePairingCandidates returned { path: 'relay', client }) dialing a desktop whose RPC surface does not implement 'pairing.provisionRelay' — i.e., an older Orca desktop version that happens to still accept relay transport but lacks the credential-install RPC. isMethodNotFound(provision) is true AND winner.path === 'relay'.
Common situations: Version skew: mobile client newer than the desktop, where the desktop exposes relay transport but predates the provisionRelay RPC. Rare in normal operation because relay transport and provisionRelay shipped together; appears in partial upgrades, custom desktop builds, or against a mock/test desktop that implements some pairing RPCs but not provisionRelay.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- relay pairing client closed
- desktop returned no relay endpoint after credential install
- relay credential install result does not match pairing journ
- ${response.error.code}: ${response.error.message}
- mobile relay pairing journal identity mismatch
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/53d47f818f3333eb.
Report an issue: GitHub.