{"record":{"id":"59de6a1dc4ad3573","repo":"Yeachan-Heo/oh-my-codex","slug":"native-hook-transaction-rollback-removal-claim-fai","errorCode":null,"errorMessage":"Native hook transaction rollback removal claim failed (${error instanceof Error ? error.message : String(error)}) and preserved ${claimPath} for manual recovery: ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}","messagePattern":"Native hook transaction rollback removal claim failed \\((.+?)\\) and preserved (.+?) for manual recovery: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/setup.ts","lineNumber":1836,"sourceCode":"\t\t\t\t`${artifact.label} rollback removal claim`,\n\t\t\t\tcurrent,\n\t\t\t\t\"rollback\",\n\t\t\t);\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tconst claimed = await captureNativeHookTransactionArtifact(\n\t\t\t\t\tclaimPath,\n\t\t\t\t\t`${artifact.label} rollback removal claim`,\n\t\t\t\t);\n\t\t\t\tawait restoreNativeHookClaim(claimPath, artifact.path, tracker);\n\t\t\t\tawait assertNativeHookTransactionArtifactSnapshot(\n\t\t\t\t\tartifact.path,\n\t\t\t\t\tartifact.label,\n\t\t\t\t\tclaimed,\n\t\t\t\t\t\"rollback\",\n\t\t\t\t);\n\t\t\t} catch (recoveryError) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Native hook transaction rollback removal claim failed (${error instanceof Error ? error.message : String(error)}) and preserved ${claimPath} for manual recovery: ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tawait rm(claimPath);\n\t} else {\n\t\tconst restoreArtifact: NativeHookTransactionArtifact = {\n\t\t\t...artifact,\n\t\t\tafter: artifact.before.bytes,\n\t\t\tafterTopology: artifact.before.topology,\n\t\t};\n\t\tawait atomicWriteNativeHookTransactionArtifact(\n\t\t\trestoreArtifact,\n\t\t\tartifact.before.bytes,\n\t\t\t\"rollback\",\n\t\t\tapplied.appliedSnapshot,\n\t\t\tancestorPrecondition,","sourceCodeStart":1818,"sourceCodeEnd":1854,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/setup.ts#L1818-L1854","documentation":"While rolling back, the transaction first claims the file (moves it aside) before restoring the pre-transaction version. If the claim itself fails and the recovery attempt to restore the claim also fails, both errors are combined and the claim path is left for manual recovery rather than risk data loss.","triggerScenarios":"Rollback encounters an error claiming artifact.path (permissions, EBUSY, missing file) and restoreNativeHookClaim for claimPath then also throws (e.g. disk full, permission removed mid-run).","commonSituations":"Restrictive file permissions, antivirus/lockers holding the file, cross-device claim directories, or injected double-faults in tests.","solutions":["Check both nested messages: the original claim error and the recovery error","Fix the underlying filesystem issue (permissions, locks, disk space)","Manually restore claimPath to artifact.path, then verify hooks still work","Re-run setup to reach a consistent state"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { access, constants } from \"node:fs/promises\";\nawait access(dirname(artifactPath), constants.W_OK); // writable dir\nawait access(claimDir, constants.W_OK);","typeGuard":null,"tryCatchPattern":"try { await tx.rollback(); } catch (e) { if (e instanceof Error && e.message.includes(\"rollback removal claim failed\")) { const claim = extractClaimPath(e.message); await restoreClaimManually(claim, artifactPath); } else throw e; }","preventionTips":["Ensure write permissions on hook files and claim dirs before running setup","Close editors/tools that lock hook files","Keep claim directory on the same filesystem/device as the hooks"],"tags":["transaction","rollback","filesystem","recovery","claim-file"],"backgroundTag":"transaction-rollback-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}