stablyai/orca · error · Error
pre-mutation hooks/list reported ${byOldKey.size} of ${reque
Error message
pre-mutation hooks/list reported ${byOldKey.size} of ${request.moves.length} moved user hooks What it means
Thrown by inspectUserHookTrust when the pre-mutation hooks/list call did not return all expected user hooks matched by their oldKey (and matching command). matchingListings builds a map keyed by normalized old key with matching command; if its size is less than moves.length, some hooks Orca expected to relocate are absent or have a different command — refusing to proceed avoids rebasing trust for a partial/inconsistent set.
Source
Thrown at src/main/codex/codex-user-hook-trust-rebase-client.ts:111
(listing) => expected.get(normalizeHookTrustKeyForLookup(listing.key)) === listing.command
)
.map((listing) => [normalizeHookTrustKeyForLookup(listing.key), listing])
)
}
function quotedKeyPath(key: string): string {
const escaped = key.replaceAll('\\', '\\\\').replaceAll('"', '\\"')
return `hooks.state."${escaped}"`
}
async function inspectUserHookTrust(
request: CodexUserHookTrustInspectRequest
): Promise<CodexUserHookTrustRebaseResult> {
return runCodexAppServerSession(request.invocation, async ({ request: requestRpc }) => {
const result = await requestRpc('hooks/list', { cwds: [request.hooksListCwd] })
const byOldKey = matchingListings(collectCodexHookListings(result), request.moves, 'oldKey')
if (byOldKey.size !== request.moves.length) {
throw new Error(
`pre-mutation hooks/list reported ${byOldKey.size} of ${request.moves.length} moved user hooks`
)
}
return {
outcome: 'inspected',
moves: request.moves.map((move) => {
const listing = byOldKey.get(normalizeHookTrustKeyForLookup(move.oldKey))!
return {
...move,
reportedOldKey: listing.key,
wasTrusted: listing.trustStatus === 'trusted',
enabled: listing.enabled
}
})
}
})
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Re-derive request.moves from a fresh hooks/list so oldKey and command match the live state.
- Ensure hooksListCwd matches the cwd used when the moves were planned.
- Remove from moves any hooks the user has since deleted.
- Confirm normalizeHookTrustKeyForLookup matches codex's current key normalization.
- Retry when no concurrent edit is in progress.
Defensive patterns
Strategy: validation
Validate before calling
// Re-derive moves from a live hooks/list so oldKey/command match before inspecting:
const live = collectCodexHookListings(await requestRpc('hooks/list', { cwds: [hooksListCwd] }))
const moves = plannedMoves.filter((m) =>
live.some((l) => normalizeHookTrustKeyForLookup(l.key) === normalizeHookTrustKeyForLookup(m.oldKey) && l.command === m.command))
if (moves.length < plannedMoves.length) {
// some hooks vanished; inspect with the filtered set instead of throwing
} Try / catch
try {
await runCodexUserHookTrustRebaseSession(request)
} catch (error) {
if (error instanceof Error && error.message.startsWith('pre-mutation hooks/list reported')) {
// re-read hooks.json, rebuild moves, retry once
} else throw error
} Prevention
- Generate request.moves from a fresh hooks/list at call time, not from a stale snapshot.
- Prevent concurrent edits to hooks.json during trust rebase.
- Ensure hooksListCwd matches the cwd used to plan the moves.
- Filter out hooks the user has since deleted before inspecting.
When it happens
Trigger: A user hook listed in request.moves was removed or renamed before the inspect call; the hook's command string changed so matchingListings (which requires command equality) excludes it; hooks/list didn't report a user-scope hook because hooksListCwd differs; normalizeHookTrustKeyForLookup collides two keys.
Common situations: Concurrent edit to hooks.json removed a hook between planning the moves and inspecting; the move's oldKey/command are stale relative to the live file; a codex version reports hook keys in a different normalized form; hooksListCwd points at a directory whose project hooks differ.
Related errors
- post-mutation hooks/list reported ${byNewKey.size} of ${requ
- post-rebase verify failed for moved user hook ${invalid.newK
- codex trust-grant entry produced no result (exit ${spawned.s
- codex app-server session already timed out
- codex app-server does not support ${method}: ${response.erro
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/80986f792f11bdca.
Report an issue: GitHub.