stablyai/orca · error · Error
relay credential rotation was not authoritatively committed
Error message
relay credential rotation was not authoritatively committed
What it means
Thrown during rotation when, after a successful `provisionRelay`, a follow-up `getEndpoints` does not report the install as `committed`, or the committed result differs (by JSON equality) from what `provisionRelay` returned. The relay server must authoritatively confirm the install across endpoints; a divergence means the install was not durably replicated.
Source
Thrown at mobile/src/transport/mobile-relay-credential-rotation.ts:65
throw new Error('relay credential rotation pending state missing')
}
let endpoints = await getEndpoints(args.client, pending.reqId)
if (endpoints.installStatus?.state !== 'committed') {
const response = await args.client.sendRequest('pairing.provisionRelay', {
reqId: pending.reqId,
newResumeTokenHash: pending.hash,
expectedCurrentHash: bundle.current.hash
})
if (!response.ok) {
throw new Error(`${response.error.code}: ${response.error.message}`)
}
const installed = DeviceCredentialInstalledSchema.parse(response.result)
endpoints = await getEndpoints(args.client, pending.reqId)
if (
endpoints.installStatus?.state !== 'committed' ||
JSON.stringify(endpoints.installStatus.result) !== JSON.stringify(installed)
) {
throw new Error('relay credential rotation was not authoritatively committed')
}
}
if (!endpoints.relay || endpoints.installStatus?.state !== 'committed') {
throw new Error('relay credential rotation endpoint state missing')
}
const installed = endpoints.installStatus.result
const next = MobileRelayCredentialBundleSchema.parse({
...bundle,
current: {
token: pending.token,
hash: pending.hash,
version: installed.currentVersion,
expiresAt: installed.resumeExpiresAt
},
...(installed.graceExpiresAt
? { grace: { ...bundle.current, expiresAt: installed.graceExpiresAt } }
: { grace: undefined }),
pending: undefinedView on GitHub (pinned to 1136503c6a)
Solutions
- Retry `getEndpoints` once after a short delay to let replication converge.
- If still divergent, abandon the rotation — do not promote an unconfirmed credential.
- Report the divergence (both `installed` and the reconciled result) for server-side investigation.
Example fix
// before
// single getEndpoints after provision — throws on transient lag
// after
let endpoints = await retryGetEndpoints(client, pending.reqId, { tries: 3, delayMs: 250 })
if (endpoints.installStatus?.state !== 'committed' ||
JSON.stringify(endpoints.installStatus.result) !== JSON.stringify(installed)) {
throw new Error('rotation unconfirmed after retries')
} Defensive patterns
Strategy: retry
Validate before calling
// No pre-call validation: divergence is observed after provisionRelay. Retry the reconciliation read.
Try / catch
try { return await rotateMobileRelayCredential(args) } catch (e) { if (e.message === 'relay credential rotation was not authoritatively committed') { await delay(500); return await rotateMobileRelayCredential(args) } throw e } Prevention
- Allow a short reconciliation delay between provisionRelay and getEndpoints.
- Never promote a credential whose committed result diverges.
- Report divergences to the server operator.
When it happens
Trigger: Server accepted `provisionRelay` but the endpoint reconciliation query returned a non-committed state or a different `result` object; eventual-consistency lag where the second `getEndpoints` hit a stale replica; server bug echoing a different result on the two calls.
Common situations: Relay cluster replication delay; a failover between the two calls; server-side race where another install superseded this `reqId`.
Related errors
- relay credential rotation endpoint state missing
- relay credential install result does not match pairing journ
- relay credential rotation pending state missing
- ${response.error.code}: ${response.error.message}
- direct pairing upgrade was not authoritatively committed
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/37dd8f0671876bd4.
Report an issue: GitHub.