{"record":{"id":"5298d7187d9de8be","repo":"stablyai/orca","slug":"post-rebase-verify-failed-for-moved-user-hook-in","errorCode":null,"errorMessage":"post-rebase verify failed for moved user hook ${invalid.newKey}","messagePattern":"post-rebase verify failed for moved user hook (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/codex/codex-user-hook-trust-rebase-client.ts","lineNumber":190,"sourceCode":"    }\n    await requestRpc('config/batchWrite', { edits, reloadUserConfig: true })\n\n    const verified = await requestRpc('hooks/list', { cwds: [request.hooksListCwd] })\n    const verifiedByKey = matchingListings(\n      collectCodexHookListings(verified),\n      request.moves,\n      'newKey'\n    )\n    const invalid = request.moves.find((move) => {\n      const listing = verifiedByKey.get(normalizeHookTrustKeyForLookup(move.newKey))\n      return (\n        !listing ||\n        (listing.trustStatus === 'trusted') !== move.wasTrusted ||\n        listing.enabled !== move.enabled\n      )\n    })\n    if (invalid) {\n      throw new Error(`post-rebase verify failed for moved user hook ${invalid.newKey}`)\n    }\n    return {\n      outcome: 'repaired',\n      repaired: request.moves.filter((move) => move.wasTrusted).length\n    }\n  })\n}\n\nexport function runCodexUserHookTrustRebaseSession(\n  request: CodexUserHookTrustRebaseRequest\n): Promise<CodexUserHookTrustRebaseResult> {\n  return request.operation === 'inspect-user-hook-trust'\n    ? inspectUserHookTrust(request)\n    : repairUserHookTrust(request)\n}\n","sourceCodeStart":172,"sourceCodeEnd":206,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex/codex-user-hook-trust-rebase-client.ts#L172-L206","documentation":"Thrown by repairUserHookTrust after config/batchWrite reapplied trust when the verify hooks/list shows at least one moved hook whose state doesn't match what was requested: either the hook is missing under newKey, its trustStatus !== 'trusted' when wasTrusted, or its enabled flag differs from the captured value. The rebase failed to fully restore trust/enable state, so it aborts rather than report success.","triggerScenarios":"config/batchWrite's hooks.state edit was rejected or partially applied by codex (e.g., hash mismatch because codex recomputed a different currentHash); the hook's enabled flag didn't stick; a concurrent edit changed trust state between write and verify; codex's trust computation differs from the hash captured at inspect time.","commonSituations":"codex version changed its trusted_hash algorithm so the captured currentHash no longer verifies; reloadUserConfig didn't fully apply; another tool toggled the hook's enabled/trust between batchWrite and verify; the hooks.state keyPath escaping in quotedKeyPath is wrong for a key with special chars.","solutions":["Re-run inspect to capture a fresh currentHash from codex, then repair — don't reuse a stale hash.","Confirm config/batchWrite with reloadUserConfig:true is honored by this codex version.","Check quotedKeyPath escaping for keys containing backslashes/quotes.","Ensure no concurrent hook-trust mutation runs during the verify window.","If codex's trust model changed, update the rebase client to match the new hooks.state schema."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Re-capture currentHash from a fresh hooks/list right before batchWrite:\nconst fresh = collectCodexHookListings(await requestRpc('hooks/list', { cwds: [hooksListCwd] }))\nconst move = request.moves.find((m) => /* matched by newKey */)\nconst freshHash = fresh.find((l) => l.key === move.reportedOldKey ?? move.newKey)?.currentHash\nif (!freshHash) { /* abort; state changed */ }","typeGuard":null,"tryCatchPattern":"try {\n  await runCodexUserHookTrustRebaseSession(request)\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('post-rebase verify failed for moved user hook')) {\n    // re-inspect to get a fresh currentHash; retry repair once with the fresh hash\n  } else throw error\n}","preventionTips":["Always capture currentHash immediately before batchWrite, not from a stale inspect.","Confirm reloadUserConfig:true is applied so verify sees the new trust.","Prevent concurrent trust mutations during the verify window.","Verify quotedKeyPath escaping for keys with backslashes or quotes.","Update the rebase client when codex changes its hooks.state/trust schema."],"tags":["codex","hooks","trust-rebase","verify","json-rpc","hash"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}