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

Refusing malformed active_skills entry ${index} in ${path}.

Error message

Refusing malformed active_skills entry ${index} in ${path}.

What it means

Thrown while validating each element of active_skills when an entry is not a plain object (null, a primitive, or an array). The validator iterates the array and requires every entry to be an object-shaped record before reading its fields. This guards against cancellation logic dereferencing non-object entries.

Source

Thrown at src/cli/index.ts:8332

      throw new Error(`Refusing contradictory owner_codex_session_id in ${path}.`);
    }
  }
}


function assertCompatibleNestedSkillOwners(
  value: Record<string, unknown>,
  authority: ExactSessionCancellationAuthority,
  path: string,
): void {
  if (!Object.prototype.hasOwnProperty.call(value, "active_skills")) return;
  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}.`);
      }
    }

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Open the state file from ${path} and find the entry at the reported index
  2. Replace the malformed entry with an object like {"skill": "name"} or delete it
  3. Re-run the cancel command
  4. If entries are systematically wrong, regenerate the state file with the command that owns it

Example fix

// before
"active_skills": ["deploy"]
// after
"active_skills": [{ "skill": "deploy", "active": true }]
Defensive patterns

Strategy: validation

Validate before calling

function activeSkillEntriesOk(v: unknown): boolean {
  const arr = (v as { active_skills?: unknown[] })?.active_skills;
  return !arr || arr.every((e) => !!e && typeof e === "object" && !Array.isArray(e));
}

Type guard

function isSkillEntry(v: unknown): v is Record<string, unknown> {
  return !!v && typeof v === "object" && !Array.isArray(v);
}

Prevention

When it happens

Trigger: A state file where active_skills contains null, a string, a number, or a nested array, e.g. {"active_skills": [null]} or {"active_skills": ["deploy"]}. The cancel command throws as soon as it reaches that entry.

Common situations: Truncated JSON from an interrupted write; state produced by a different schema version; manual edits that replaced an entry with a scalar; third-party tooling writing simplified skill lists.

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.

Related errors


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