Yeachan-Heo/oh-my-codex · error · Error
Native hook transaction failed and was rolled back: ${messag
Error message
Native hook transaction failed and was rolled back: ${message} What it means
A native hook transaction hit an error during apply, but rollback completed successfully and restored all artifacts to their pre-transaction state. The original error message is wrapped to make clear that no manual recovery is needed — the system is back to where it started.
Source
Thrown at src/cli/setup.ts:2141
ancestorPrecondition,
tracker,
undefined,
applied,
);
await assertNativeHookTransactionRollbackState(applied);
} catch (cleanupError) {
rollbackFailures.push(
`staged deletion cleanup: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,
);
}
}
const message = error instanceof Error ? error.message : String(error);
if (rollbackFailures.length > 0) {
throw new Error(
`Native hook transaction failed (${message}) and rollback failed; manual recovery is required (${rollbackFailures.join("; ")}).`,
);
}
throw new Error(`Native hook transaction failed and was rolled back: ${message}`);
}
}
async function ensureBackup(
destinationPath: string,
contentChanged: boolean,
backupContext: SetupBackupContext,
options: Pick<SetupOptions, "dryRun" | "verbose">,
): Promise<boolean> {
if (!contentChanged || !existsSync(destinationPath)) return false;
const relativePath = relative(backupContext.baseRoot, destinationPath);
const safeRelativePath =
relativePath.startsWith("..") || relativePath === ""
? destinationPath.replace(/^[/]+/, "")
: relativePath;
const backupPath = join(backupContext.backupRoot, safeRelativePath);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Read the wrapped message to find the original apply failure and fix it
- Simply re-run setup after addressing the cause — state was rolled back cleanly
- If the cause was concurrent modification, prevent overlapping runs
- No manual file recovery is required
Defensive patterns
Strategy: try-catch
Try / catch
try { await tx.apply(); } catch (e) { if (e instanceof Error && e.message.includes("failed and was rolled back")) { /* safe to retry after fixing the wrapped cause */ await fixCauseAndRerun(); } else throw e; } Prevention
- Read the wrapped message to fix the root cause before retrying
- Retry setup after transient failures — rollback was clean
- Log but do not manually edit files in this case
When it happens
Trigger: Any apply-phase failure (invalid hooks output, verification failure, claim failure) where every rollback step succeeds, leaving rollbackFailures empty.
Common situations: Transient write/verification failures, invalid generated hooks content, or single-point fault injection where recovery paths are healthy.
Related errors
- Native hook transaction rollback preserved ${artifact.path}
- Native hook transaction rollback removal claim failed (${err
- Native hook transaction rollback preserved ${artifact.path}
- Native hook transaction failed (${message}) and rollback fai
- preLaunch ${completion.operation} failed
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/5fafd9ab1768c5e2.
Report an issue: GitHub.