{"record":{"id":"24616b8c5f989d4e","repo":"Yeachan-Heo/oh-my-codex","slug":"refusing-malformed-active-skills-in-path","errorCode":null,"errorMessage":"Refusing malformed active_skills in ${path}.","messagePattern":"Refusing malformed active_skills in (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/index.ts","lineNumber":8327,"sourceCode":"  if (Object.prototype.hasOwnProperty.call(value, \"owner_codex_session_id\")) {\n    const rawOwner = value.owner_codex_session_id;\n    const blankOwner = typeof rawOwner === \"string\" && rawOwner.trim() === \"\";\n    const owner = normalizeSessionId(rawOwner);\n    if (!blankOwner && (!owner || (!allowStaleTopCodexOwner && owner !== authority.nativeSessionId))) {\n      throw new Error(`Refusing contradictory owner_codex_session_id in ${path}.`);\n    }\n  }\n}\n\n\nfunction assertCompatibleNestedSkillOwners(\n  value: Record<string, unknown>,\n  authority: ExactSessionCancellationAuthority,\n  path: string,\n): void {\n  if (!Object.prototype.hasOwnProperty.call(value, \"active_skills\")) return;\n  if (!Array.isArray(value.active_skills)) {\n    throw new Error(`Refusing malformed active_skills in ${path}.`);\n  }\n  for (const [index, skill] of value.active_skills.entries()) {\n    const entryPath = `${path} active_skills[${index}]`;\n    if (!skill || typeof skill !== \"object\" || Array.isArray(skill)) {\n      throw new Error(`Refusing malformed active_skills entry ${index} in ${path}.`);\n    }\n    const entry = skill as Record<string, unknown>;\n    if (typeof entry.skill !== \"string\" || entry.skill.trim() === \"\") {\n      throw new Error(`Refusing malformed skill in ${entryPath}.`);\n    }\n    for (const field of [\"active\"] as const) {\n      if (Object.prototype.hasOwnProperty.call(entry, field) && typeof entry[field] !== \"boolean\") {\n        throw new Error(`Refusing malformed ${field} in ${entryPath}.`);\n      }\n    }\n    if (Object.prototype.hasOwnProperty.call(entry, \"phase\") && typeof entry.phase !== \"string\") {\n      throw new Error(`Refusing malformed phase in ${entryPath}.`);\n    }","sourceCodeStart":8309,"sourceCodeEnd":8345,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L8309-L8345","documentation":"This error is thrown by the session-cancellation state validator when a loaded state document contains an active_skills property that is not an array. The CLI refuses to operate on state files whose shape it cannot safely interpret, treating a malformed active_skills collection as corruption rather than best-effort parsing it. It exists to prevent cancellation logic from mutating partially understood state.","triggerScenarios":"Calling the cancel command on a workspace whose state JSON has active_skills set to an object, string, number, or null (e.g. {\"active_skills\": {\"skill\": \"x\"}} or {\"active_skills\": null}). Also triggered if an external tool or hand-edit wrote the state file with a non-array value.","commonSituations":"Hand-edited state files; older/newer CLI versions that serialized active_skills differently; external scripts or editors that rewrote state JSON and changed the type; corrupted or partially-written state files after a crash.","solutions":["Inspect the state file named in ${path} and check the active_skills field's type","Fix active_skills to be an array of skill entries, or remove the property entirely","If the file was written by a different tool version, regenerate or re-sync the state via the owning command","Restore from a backup state file if the content is unrecoverable"],"exampleFix":"// before\n\"active_skills\": { \"build\": true }\n// after\n\"active_skills\": [{ \"skill\": \"build\", \"active\": true }]","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction stateHasValidActiveSkills(path: string): boolean {\n  const parsed = JSON.parse(readFileSync(path, \"utf-8\"));\n  if (!Object.prototype.hasOwnProperty.call(parsed, \"active_skills\")) return true;\n  return Array.isArray(parsed.active_skills);\n}","typeGuard":"function hasWellFormedActiveSkills(v: unknown): v is { active_skills?: unknown[] } {\n  if (!v || typeof v !== \"object\" || Array.isArray(v)) return false;\n  const rec = v as Record<string, unknown>;\n  return !Object.prototype.hasOwnProperty.call(rec, \"active_skills\") || Array.isArray(rec.active_skills);\n}","tryCatchPattern":null,"preventionTips":["Validate state JSON against the expected schema before running cancel","Never hand-edit state files while the CLI is running","Back up state files before external tools rewrite them"],"tags":["state-validation","cli","corrupt-state","cancel"],"backgroundTag":"schema-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}