{"record":{"id":"abc59ac0a3e64978","repo":"Yeachan-Heo/oh-my-codex","slug":"catalog-manifest-invalid-schemaversion","errorCode":null,"errorMessage":"catalog_manifest_invalid:schemaVersion","messagePattern":"catalog_manifest_invalid:schemaVersion","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/catalog/schema.ts","lineNumber":47,"sourceCode":"const AGENT_CATEGORIES = new Set<CatalogAgentCategory>(['build', 'review', 'domain', 'product', 'coordination']);\nconst ENTRY_STATUSES = new Set<CatalogEntryStatus>(['active', 'alias', 'merged', 'deprecated', 'internal']);\nconst REQUIRED_CORE_SKILLS = new Set(['autopilot', 'ralplan', 'team', 'ultragoal']);\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertNonEmptyString(value: unknown, field: string): asserts value is string {\n  if (typeof value !== 'string' || value.trim() === '') {\n    throw new Error(`catalog_manifest_invalid:${field}`);\n  }\n}\n\nexport function validateCatalogManifest(input: unknown): CatalogManifest {\n  if (!isObject(input)) throw new Error('catalog_manifest_invalid:root');\n\n  if (typeof input.schemaVersion !== 'number' || !Number.isInteger(input.schemaVersion)) {\n    throw new Error('catalog_manifest_invalid:schemaVersion');\n  }\n\n  assertNonEmptyString(input.catalogVersion, 'catalogVersion');\n\n  if (!Array.isArray(input.skills)) throw new Error('catalog_manifest_invalid:skills');\n  if (!Array.isArray(input.agents)) throw new Error('catalog_manifest_invalid:agents');\n\n  const seenSkills = new Set<string>();\n  const skills: CatalogSkillEntry[] = input.skills.map((entry, index) => {\n    if (!isObject(entry)) throw new Error(`catalog_manifest_invalid:skills[${index}]`);\n    assertNonEmptyString(entry.name, `skills[${index}].name`);\n    assertNonEmptyString(entry.category, `skills[${index}].category`);\n    assertNonEmptyString(entry.status, `skills[${index}].status`);\n\n    if (!SKILL_CATEGORIES.has(entry.category as CatalogSkillCategory)) {\n      throw new Error(`catalog_manifest_invalid:skills[${index}].category`);\n    }\n    if (!ENTRY_STATUSES.has(entry.status as CatalogEntryStatus)) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/catalog/schema.ts#L29-L65","documentation":"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.","triggerScenarios":"A manifest where \"schemaVersion\" is absent, quoted (\"schemaVersion\": \"2\"), or non-integer like 1.5.","commonSituations":"Hand-writing a manifest and quoting the version, or a newer/older generator emitting a different shape than this validator expects.","solutions":["Set schemaVersion to an unquoted integer matching the version this library expects (e.g. 1)","Regenerate the manifest with the tooling bundled with your installed version","If the mismatch persists, align the installed library version with the manifest generator version"],"exampleFix":"// before\n{ \"schemaVersion\": \"1\", ... }\n\n// after\n{ \"schemaVersion\": 1, ... }","handlingStrategy":"validation","validationCode":"const raw = JSON.parse(text);\nif (typeof raw.schemaVersion !== 'number' || !Number.isInteger(raw.schemaVersion)) { /* fix before reading */ }","typeGuard":"function hasIntegerSchemaVersion(v: unknown): v is { schemaVersion: number } {\n  return typeof v === 'object' && v !== null && typeof (v as any).schemaVersion === 'number' && Number.isInteger((v as any).schemaVersion);\n}","tryCatchPattern":null,"preventionTips":["Keep schemaVersion an unquoted integer","Regenerate manifests when upgrading the library"],"tags":["catalog","manifest","version","validation"],"backgroundTag":"schema-version-mismatch","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}