stablyai/orca · error · Error
Codex reset attempt idempotency key is invalid
Error message
Codex reset attempt idempotency key is invalid
What it means
Thrown by `getOrCreateCodexResetAttempt` when a new attempt must be created (no existing entry) and the caller-supplied `createIdempotencyKey()` returns a value that fails `IdempotencyKeySchema` — which is `z.uuid()`. The idempotency key is what makes the downstream reset RPC safely retryable after a lost response, so it must be a well-formed UUID before it is ever persisted.
Source
Thrown at mobile/src/storage/codex-reset-attempt-journal.ts:147
if (scopeMutations.get(key) === tail) {
scopeMutations.delete(key)
}
}
}
export async function getOrCreateCodexResetAttempt(
identity: AttemptIdentity & { createIdempotencyKey: () => string }
): Promise<CodexResetAttempt> {
return withScopeMutation(identity, async () => {
const key = storageKey(identity)
const raw = await AsyncStorage.getItem(key)
if (raw !== null) {
return parseAttempt(raw, identity)
}
const idempotencyKey = identity.createIdempotencyKey()
if (!IdempotencyKeySchema.safeParse(idempotencyKey).success) {
throw new Error('Codex reset attempt idempotency key is invalid')
}
const attempt = CodexResetAttemptSchema.parse({
v: 1,
hostId: identity.hostId,
expectedScope: identity.expectedScope,
idempotencyKey
})
// Why: the key must survive a committed provider mutation whose response is
// lost; no reset RPC may start until this write has completed successfully.
await AsyncStorage.setItem(key, JSON.stringify(attempt))
return attempt
})
}
export async function clearCodexResetAttemptAfterAuthoritativeResponse(
identity: AttemptIdentity & { idempotencyKey: string }
): Promise<void> {
return withScopeMutation(identity, async () => {View on GitHub (pinned to 1136503c6a)
Solutions
- Make `createIdempotencyKey` return a canonical lowercase v4 UUID (e.g. via `crypto.randomUUID()` or `uuid.v4()`).
- Add a unit test asserting the generator output passes `z.uuid()`.
- Strip braces and lowercase the value before returning if using a legacy UUID formatter.
- If using a custom generator, validate it against the UUID regex `^[0-9a-f]{8}-...$` upstream.
Example fix
// before — non-UUID key
createIdempotencyKey: () => `${Date.now()}`
// after — canonical UUID
createIdempotencyKey: () => crypto.randomUUID() Defensive patterns
Strategy: validation
Validate before calling
// Validate the key shape before it reaches the journal.
import { z } from 'zod'
const IdempotencyKeySchema = z.uuid()
const key = identity.createIdempotencyKey()
if (!IdempotencyKeySchema.safeParse(key).success) {
throw new Error('createIdempotencyKey must return a canonical UUID')
} Type guard
function isUuid(value: string): boolean {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)
} Prevention
- Implement createIdempotencyKey with crypto.randomUUID() or uuid.v4().
- Unit-test the generator against z.uuid().
- Never substitute timestamps or short random strings for the idempotency key.
When it happens
Trigger: First-time reset for an account scope where AsyncStorage has no entry, and the `createIdempotencyKey` callback returns a non-UUID string (wrong format, empty, contains invalid characters, or not lowercase canonical form).
Common situations: The key generator uses a non-UUID source (timestamp, random hex of wrong length); a UUID library returns an uppercased or braced form that `z.uuid()` rejects; the callback was stubbed incorrectly in tests; v4 vs v1 UUID format mismatch.
Related errors
- Invalid accounts snapshot from host
- Codex reset attempt journal is unreadable
- Codex reset attempt journal identity changed
- linear_invalid_write_id
- Invalid pet.json: ${error instanceof Error ? error.message :
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/27bcc6ea42537c29.
Report an issue: GitHub.