Yeachan-Heo/oh-my-codex · critical · Error
Native hook transaction committed but staged deletion cleanu
Error message
Native hook transaction committed but staged deletion cleanup failed during finalization: ${error instanceof Error ? error.message : String(error)} What it means
After a native hook transaction commits and staged-deletion cleanup has already run for at least one artifact, a later finalization failure cannot be safely rolled back (cleanup already deleted the pre-states). This error surfaces that the commit stands but finalization did not complete, wrapping the underlying error.
Source
Thrown at src/cli/setup.ts:2086
await cleanupNativeHookTransactionStagedDeletions(
applied,
ancestorPrecondition,
tracker,
preconditions,
);
injectNativeHookTransactionFailure(
"after_staged_cleanup",
artifacts[artifacts.length - 1],
);
await assertUnmutatedNativeHookTransactionPreconditions(preconditions, applied);
await assertNativeHookTransactionAncestorPrecondition(ancestorPrecondition);
await assertAppliedNativeHookTransactionSnapshots(applied);
} catch (error) {
if (
stagedCleanupStarted &&
applied.some((entry) => entry.stagedDeletionCleaned)
) {
throw new Error(
`Native hook transaction committed but staged deletion cleanup failed during finalization: ${error instanceof Error ? error.message : String(error)}`,
);
}
const rollbackFailures: string[] = [];
const restored: AppliedNativeHookTransactionArtifact[] = [];
try {
await assertNativeHookTransactionRollbackState(applied);
} catch (rollbackError) {
rollbackFailures.push(
`recovery preflight: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`,
);
}
if (rollbackFailures.length === 0) {
for (const entry of [...applied].reverse()) {
try {
await assertNativeHookTransactionRollbackState(applied);
await restoreNativeHookTransactionArtifact(
entry,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Treat the transaction as committed; do NOT attempt manual rollback of already-cleaned artifacts
- Read the wrapped error message to find the finalization step that failed and address it
- Re-run setup to converge to the desired end state
- Check that no external process modified hook files during finalization
Defensive patterns
Strategy: try-catch
Try / catch
try { await tx.finalize(); } catch (e) { if (e instanceof Error && e.message.includes("committed but staged deletion cleanup failed")) { /* treat as committed; fix wrapped finalization error; re-run setup */ } else throw e; } Prevention
- Do not kill setup mid-finalization
- Keep hook files untouched until setup exits
- Re-run setup to converge rather than manual rollback
When it happens
Trigger: assertAppliedNativeHookTransactionSnapshots (or another finalization step) throws after stagedCleanupStarted and some entries have stagedDeletionCleaned set.
Common situations: Post-commit verification racing external file edits, or fault injection after the no-rollback point in tests.
Related errors
- Native hook transaction staged deletion cleanup claim failed
- preLaunch setup finalization failed
- detached child process group did not disappear after forced
- bound session retained close failed: ${closeEvidence.error?.
- detached post-launch lifecycle cleanup failed
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/ec6c637a7c8acdf4.
Report an issue: GitHub.