Yeachan-Heo/oh-my-codex · error · Error

Native hook transaction staged deletion cleanup claim failed

Error message

Native hook transaction staged deletion cleanup claim failed (${error instanceof Error ? error.message : String(error)}) and preserved ${claimPath} for manual recovery: ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}

What it means

After a transaction commits staged deletions, cleanup must claim and remove the staged files. If reading back / claiming a staged deletion fails and the attempt to restore the claim also fails, both errors are reported and the claim file is preserved for manual recovery.

Source

Thrown at src/cli/setup.ts:1932

			`${entry.artifact.label} staged deletion`,
			stagedDeletionSnapshot,
			"read-back",
		);
		await assertNativeHookTransactionAncestorPrecondition(ancestorPrecondition);
		const claimPath = nativeHookTransactionClaimPath(entry.artifact.path);
		await rename(stagedDeletionPath, claimPath);
		try {
			await assertNativeHookTransactionArtifactSnapshot(
				claimPath,
				`${entry.artifact.label} staged deletion cleanup claim`,
				stagedDeletionSnapshot,
				"read-back",
			);
		} catch (error) {
			try {
				await restoreNativeHookClaim(claimPath, stagedDeletionPath, tracker);
			} catch (recoveryError) {
				throw new Error(
					`Native hook transaction staged deletion cleanup claim failed (${error instanceof Error ? error.message : String(error)}) and preserved ${claimPath} for manual recovery: ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`,
				);
			}
			throw error;
		}
		await rm(claimPath);
		entry.stagedDeletionCleaned = true;
		if (rollbackApplied) {
			await assertNativeHookTransactionRollbackState(rollbackApplied);
		}
	}
}

function nativeHookTransactionBackupPath(
	artifactPath: string,
	backupContext: SetupBackupContext,
): string {
	const relativePath = relative(backupContext.baseRoot, artifactPath);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Inspect both nested error messages to identify the staged file and failure mode
  2. Manually delete or restore claimPath depending on whether the deletion was intended
  3. Ensure the staging directory is writable and untouched during the transaction
  4. Re-run setup; staged deletions already cleaned are skipped via stagedDeletionCleaned
Defensive patterns

Strategy: try-catch

Validate before calling

import { access } from "node:fs/promises";
for (const p of stagedPaths) await access(p); // staged files still present and readable

Try / catch

try { await tx.commit(); } catch (e) { if (e instanceof Error && e.message.includes("staged deletion cleanup claim failed")) { /* remove or restore claimPath per intent, then re-run setup */ } else throw e; }

Prevention

When it happens

Trigger: cleanupNativeHookTransactionStagedDeletions fails on a staged file (read-back mismatch, permission error) and the subsequent restoreNativeHookClaim for that claim path also throws.

Common situations: Permission changes between commit and cleanup, external deletion of staged files, disk errors, or injected faults in durability tests.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/feefb441b6424f69. Report an issue: GitHub.