Yeachan-Heo/oh-my-codex · error · Error
Refusing malformed phase in ${entryPath}.
Error message
Refusing malformed phase in ${entryPath}. What it means
An active_skills entry may optionally carry a phase field, which must be a string when present. This error fires when phase exists but is not a string (number, boolean, object, null). phase typically labels a skill's lifecycle stage, so a non-string value signals schema corruption the library will not silently accept.
Source
Thrown at src/cli/index.ts:8344
if (!Array.isArray(value.active_skills)) {
throw new Error(`Refusing malformed active_skills in ${path}.`);
}
for (const [index, skill] of value.active_skills.entries()) {
const entryPath = `${path} active_skills[${index}]`;
if (!skill || typeof skill !== "object" || Array.isArray(skill)) {
throw new Error(`Refusing malformed active_skills entry ${index} in ${path}.`);
}
const entry = skill as Record<string, unknown>;
if (typeof entry.skill !== "string" || entry.skill.trim() === "") {
throw new Error(`Refusing malformed skill in ${entryPath}.`);
}
for (const field of ["active"] as const) {
if (Object.prototype.hasOwnProperty.call(entry, field) && typeof entry[field] !== "boolean") {
throw new Error(`Refusing malformed ${field} in ${entryPath}.`);
}
}
if (Object.prototype.hasOwnProperty.call(entry, "phase") && typeof entry.phase !== "string") {
throw new Error(`Refusing malformed phase in ${entryPath}.`);
}
for (const [field, fieldValue] of Object.entries(entry)) {
if (field.endsWith("_at") && typeof fieldValue !== "string") {
throw new Error(`Refusing malformed ${field} in ${entryPath}.`);
}
}
assertExactSkillOwner(entry, authority, entryPath);
}
}
interface CancellationTestFaults {
writeFailureMode?: string;
rollbackFailureMode?: string;
}
async function cancelModes(
args: string[] = [],
options: { cwd?: string; testFaults?: CancellationTestFaults } = {},View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Change phase to a string (e.g. 2 -> "2") or remove the field
- If the value is meaningful, map it to the correct string phase label for your version
- Retry the cancel command
- Check release notes for phase schema changes after upgrading
Example fix
// before
{ "skill": "x", "phase": 2 }
// after
{ "skill": "x", "phase": "build" } Defensive patterns
Strategy: validation
Validate before calling
function phasesValid(entries: Record<string, unknown>[]): boolean {
return entries.every((e) => !Object.prototype.hasOwnProperty.call(e, "phase") || typeof e.phase === "string");
} Type guard
function isOptionalString(v: unknown): v is string | undefined {
return v === undefined || typeof v === "string";
} Prevention
- Keep phase as a labeled string
- Check schema notes when upgrading versions that redefine phase
When it happens
Trigger: A state entry like {"skill": "x", "phase": 2} or {"skill": "x", "phase": null}; the presence check passes but typeof entry.phase !== "string" is true.
Common situations: Schema changes between versions that made phase numeric; hand edits; migration scripts copying incompatible values into phase.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Refusing malformed ${field} in ${entryPath}.
- Refusing malformed active_skills in ${path}.
- Refusing malformed active_skills entry ${index} in ${path}.
- Refusing malformed skill in ${entryPath}.
- omx cancel --all is not supported; broad workspace cancellat
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/8fa3bf0fd14f7f99.
Report an issue: GitHub.