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

catalog_manifest_invalid:schemaVersion

Error message

catalog_manifest_invalid:schemaVersion

What it means

The manifest validator requires schemaVersion to be an integer number; catalog_manifest_invalid:schemaVersion fires when it is a string (like "1"), a float, or missing. This guards against manifest format drift between generator and reader versions.

Source

Thrown at src/catalog/schema.ts:47

const AGENT_CATEGORIES = new Set<CatalogAgentCategory>(['build', 'review', 'domain', 'product', 'coordination']);
const ENTRY_STATUSES = new Set<CatalogEntryStatus>(['active', 'alias', 'merged', 'deprecated', 'internal']);
const REQUIRED_CORE_SKILLS = new Set(['autopilot', 'ralplan', 'team', 'ultragoal']);

function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function assertNonEmptyString(value: unknown, field: string): asserts value is string {
  if (typeof value !== 'string' || value.trim() === '') {
    throw new Error(`catalog_manifest_invalid:${field}`);
  }
}

export function validateCatalogManifest(input: unknown): CatalogManifest {
  if (!isObject(input)) throw new Error('catalog_manifest_invalid:root');

  if (typeof input.schemaVersion !== 'number' || !Number.isInteger(input.schemaVersion)) {
    throw new Error('catalog_manifest_invalid:schemaVersion');
  }

  assertNonEmptyString(input.catalogVersion, 'catalogVersion');

  if (!Array.isArray(input.skills)) throw new Error('catalog_manifest_invalid:skills');
  if (!Array.isArray(input.agents)) throw new Error('catalog_manifest_invalid:agents');

  const seenSkills = new Set<string>();
  const skills: CatalogSkillEntry[] = input.skills.map((entry, index) => {
    if (!isObject(entry)) throw new Error(`catalog_manifest_invalid:skills[${index}]`);
    assertNonEmptyString(entry.name, `skills[${index}].name`);
    assertNonEmptyString(entry.category, `skills[${index}].category`);
    assertNonEmptyString(entry.status, `skills[${index}].status`);

    if (!SKILL_CATEGORIES.has(entry.category as CatalogSkillCategory)) {
      throw new Error(`catalog_manifest_invalid:skills[${index}].category`);
    }
    if (!ENTRY_STATUSES.has(entry.status as CatalogEntryStatus)) {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Set schemaVersion to an unquoted integer matching the version this library expects (e.g. 1)
  2. Regenerate the manifest with the tooling bundled with your installed version
  3. If the mismatch persists, align the installed library version with the manifest generator version

Example fix

// before
{ "schemaVersion": "1", ... }

// after
{ "schemaVersion": 1, ... }
Defensive patterns

Strategy: validation

Validate before calling

const raw = JSON.parse(text);
if (typeof raw.schemaVersion !== 'number' || !Number.isInteger(raw.schemaVersion)) { /* fix before reading */ }

Type guard

function hasIntegerSchemaVersion(v: unknown): v is { schemaVersion: number } {
  return typeof v === 'object' && v !== null && typeof (v as any).schemaVersion === 'number' && Number.isInteger((v as any).schemaVersion);
}

Prevention

When it happens

Trigger: A manifest where "schemaVersion" is absent, quoted ("schemaVersion": "2"), or non-integer like 1.5.

Common situations: Hand-writing a manifest and quoting the version, or a newer/older generator emitting a different shape than this validator expects.

Related errors


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