stablyai/orca · error · Error
relay credential install result does not match pairing journ
Error message
relay credential install result does not match pairing journal
What it means
Thrown by `promotePairingJournalCredential` when the install RPC result's `reqId` or `authorizationMode` does not match what the pairing journal recorded in its metadata. The journal is the durable record of which install request was initiated; the install result must echo the same `installReqId` and `authorizationMode` or the promotion is unsafe (it could install a credential from a different authorization flow).
Source
Thrown at mobile/src/transport/mobile-relay-credential-bundle.ts:59
})
.strict()
export type MobileRelayCredentialBundle = z.infer<typeof MobileRelayCredentialBundleSchema>
function credentialKey(hostId: string): string {
return `orca.mobile-relay.credentials.${hostId}`
}
export function promotePairingJournalCredential(args: {
journal: MobileRelayPairingJournal
installed: DeviceCredentialInstalled
}): MobileRelayCredentialBundle {
const { journal, installed } = args
if (
installed.reqId !== journal.metadata.installReqId ||
installed.authorizationMode !== journal.metadata.authorizationMode
) {
throw new Error('relay credential install result does not match pairing journal')
}
return MobileRelayCredentialBundleSchema.parse({
v: 1,
hostId: journal.metadata.host.id,
deviceToken: journal.secrets.deviceToken,
current: {
token: journal.secrets.pendingResumeToken,
hash: journal.metadata.pendingResumeTokenHash,
version: installed.currentVersion,
expiresAt: installed.resumeExpiresAt
}
})
}
export async function readMobileRelayCredentialBundle(
hostId: string
): Promise<MobileRelayCredentialBundle | null> {
requireNativeSecretStore()View on GitHub (pinned to 1136503c6a)
Solutions
- Ensure only one pairing flow is active per host at a time — clear the journal before starting fresh.
- Verify the `installReqId` you pass matches `journal.metadata.installReqId` before calling promote.
- If the journal is stale, discard it and re-run pairing from the start.
Example fix
// before
promotePairingJournalCredential({ journal: oldJournal, installed: freshInstall })
// -> install result does not match pairing journal
// after
if (installed.reqId !== journal.metadata.installReqId ||
installed.authorizationMode !== journal.metadata.authorizationMode) {
await discardPairingJournal(hostId)
throw new Error('journal/install mismatch — restart pairing')
}
return promotePairingJournalCredential({ journal, installed }) Defensive patterns
Strategy: validation
Validate before calling
function installMatchesJournal(journal: MobileRelayPairingJournal, installed: DeviceCredentialInstalled): boolean {
return installed.reqId === journal.metadata.installReqId &&
installed.authorizationMode === journal.metadata.authorizationMode
}
if (!installMatchesJournal(journal, installed)) { await discardJournal(); throw new Error('mismatch') } Type guard
function isJournalMatch(j: MobileRelayPairingJournal, i: DeviceCredentialInstalled): boolean {
return i.reqId === j.metadata.installReqId && i.authorizationMode === j.metadata.authorizationMode
} Try / catch
try { promotePairingJournalCredential({ journal, installed }) } catch (e) { if (e.message === 'relay credential install result does not match pairing journal') { await clearPairingJournal(hostId); rethrowAsRepairable(e) } else throw e } Prevention
- Serialize pairing flows per host — never run two in parallel.
- Clear the journal before starting a fresh pairing attempt.
- Cross-check installReqId against the journal before promote.
When it happens
Trigger: Passing an `installed` result from a different pairing attempt than the journal refers to; concurrent pairing flows racing on the same host; journal corruption where `metadata.installReqId` is stale; a server that echoes a different `authorizationMode` than requested.
Common situations: Two pairing attempts running in parallel (e.g. user retried while the first was in flight); a journal that was not cleared after a failed attempt; server-side bug returning the wrong mode.
Related errors
- relay credential rotation was not authoritatively committed
- relay credential rotation endpoint state missing
- direct pairing upgrade was not authoritatively committed
- relay credential rotation pending state missing
- ${response.error.code}: ${response.error.message}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/26e002aed9b52e11.
Report an issue: GitHub.