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

Native hook transaction rollback removal claim failed (${err

Error message

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)}

What it means

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.

Source

Thrown at src/cli/setup.ts:1836

				`${artifact.label} rollback removal claim`,
				current,
				"rollback",
			);
		} catch (error) {
			try {
				const claimed = await captureNativeHookTransactionArtifact(
					claimPath,
					`${artifact.label} rollback removal claim`,
				);
				await restoreNativeHookClaim(claimPath, artifact.path, tracker);
				await assertNativeHookTransactionArtifactSnapshot(
					artifact.path,
					artifact.label,
					claimed,
					"rollback",
				);
			} catch (recoveryError) {
				throw new Error(
					`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)}`,
				);
			}
			throw error;
		}
		await rm(claimPath);
	} else {
		const restoreArtifact: NativeHookTransactionArtifact = {
			...artifact,
			after: artifact.before.bytes,
			afterTopology: artifact.before.topology,
		};
		await atomicWriteNativeHookTransactionArtifact(
			restoreArtifact,
			artifact.before.bytes,
			"rollback",
			applied.appliedSnapshot,
			ancestorPrecondition,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check both nested messages: the original claim error and the recovery error
  2. Fix the underlying filesystem issue (permissions, locks, disk space)
  3. Manually restore claimPath to artifact.path, then verify hooks still work
  4. Re-run setup to reach a consistent state
Defensive patterns

Strategy: try-catch

Validate before calling

import { access, constants } from "node:fs/promises";
await access(dirname(artifactPath), constants.W_OK); // writable dir
await access(claimDir, constants.W_OK);

Try / catch

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; }

Prevention

When it happens

Trigger: 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).

Common situations: Restrictive file permissions, antivirus/lockers holding the file, cross-device claim directories, or injected double-faults in tests.

Related errors


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