Yeachan-Heo/oh-my-codex · error · ManagedCodexHooksPlanError
invalid_document
invalid_document
Error message
Refusing to remove managed notification dispatcher: metadata ${metadataPath} is missing. What it means
A ManagedCodexHooksPlanError (code invalid_document) thrown when planning removal of the managed notification dispatcher: the metadata snapshot has no bytes, i.e. the metadata file tracked for the transaction does not exist. The planner refuses to deconfigure hooks without proof it wrote them.
Source
Thrown at src/cli/setup.ts:3626
lines.splice(nextFeaturesStart, nextSectionEnd - nextFeaturesStart);
}
}
return lines.join("\n");
}
interface DisableHooksNotifyPlan {
finalConfig: string;
metadataPath?: string;
metadataAfter: Buffer | null;
}
function parseDisableHooksNotifyMetadata(
snapshot: NativeHookTransactionArtifactSnapshot,
metadataPath: string,
currentNotify: readonly string[],
): string[] | null {
if (!snapshot.bytes) {
throw new ManagedCodexHooksPlanError(
"invalid_document",
`Refusing to remove managed notification dispatcher: metadata ${metadataPath} is missing.`,
);
}
let parsed: unknown;
try {
parsed = JSON.parse(decodeNativeHookTransactionUtf8(snapshot.bytes, `notification metadata ${metadataPath}`));
} catch (error) {
throw new ManagedCodexHooksPlanError(
"invalid_document",
`Refusing to remove managed notification dispatcher: metadata ${metadataPath} is invalid JSON (${error instanceof Error ? error.message : String(error)}).`,
);
}
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
throw new ManagedCodexHooksPlanError("invalid_document", `Refusing to remove managed notification dispatcher: metadata ${metadataPath} must be an object.`);
}
const metadata = parsed as Record<string, unknown>;
const dispatcherNotify = metadata.dispatcherNotify;View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Restore or re-run `omx setup` to regenerate managed hook metadata, then disable again
- Verify CODEX_HOME env var matches the home used when hooks were installed
- Manually remove the notify entry from config.toml if you intentionally discarded the metadata and accept losing the pre-OMX value
Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync } from 'node:fs';
// before disabling hooks:
if (!existsSync(getNotifyMetadataPath(codexHome))) {
// regenerate via setup or bail with a clear message
} Type guard
function isManagedPlanError(e: unknown): e is { code: string; message: string } {
return typeof e === 'object' && e !== null && 'code' in e && (e as any).code === 'invalid_document';
} Try / catch
try { await disableHooks(); } catch (e) { if (isManagedPlanError(e) && /metadata .* is missing/.test(e.message)) { await runSetupToRegenerateMetadata(); } else throw e; } Prevention
- Never manually delete OMX metadata files under the codex home
- Keep CODEX_HOME stable between enable and disable operations
When it happens
Trigger: Running disable-hooks while the OMX notify metadata JSON file at the expected path has been deleted, moved, or never written (partial earlier install, manual cleanup of ~/.codex).
Common situations: User manually deleted the OMX metadata file, a previous install crashed mid-transaction, or CODEX_HOME points at a different directory than the one used at install time.
Related errors
- Native hook transaction wrote invalid hooks.json: ${validati
- Missing notification metadata snapshot for ${notifyPlan.meta
- Missing notification metadata snapshot for ${metadataPath};
- formatCodexGoalReconciliation(reconciliation)
- unsupported codex login flag for omx auth add: ${arg}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/3293b1ce2edec45a.
Report an issue: GitHub.