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

  1. Restore or re-run `omx setup` to regenerate managed hook metadata, then disable again
  2. Verify CODEX_HOME env var matches the home used when hooks were installed
  3. 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

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


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