openclaw/openclaw · error · Error

${key} must be an integer

Error message

${key} must be an integer

What it means

Thrown by readIntegerParam when a value is present for an integer parameter but is not a number or fails Number.isInteger. The only caller is codex_sessions_list reading 'max_stored_sessions'. This is defense-in-depth behind the Typebox SessionsListParamsSchema which should already reject non-integers before execute() runs.

Source

Thrown at extensions/codex/src/supervision-tools.ts:219

    if (!isRecord(entry)) {
      throw new Error(`Codex thread/list returned an invalid entry at data[${index}]`);
    }
    readCompatThreadId(entry.id, "thread/list", index);
    return entry;
  });
}

function readBooleanParam(params: Record<string, unknown>, key: string): boolean {
  return params[key] === true;
}

function readIntegerParam(params: Record<string, unknown>, key: string): number | undefined {
  const value = params[key];
  if (value === undefined) {
    return undefined;
  }
  if (typeof value !== "number" || !Number.isInteger(value)) {
    throw new Error(`${key} must be an integer`);
  }
  if (value < 1 || value > 1000) {
    throw new Error(`${key} must be between 1 and 1000`);
  }
  return value;
}

function readModeParam(params: Record<string, unknown>): CodexSupervisorTurnMode | undefined {
  const mode = readStringParam(params, "mode");
  if (!mode) {
    return undefined;
  }
  if (mode === "auto" || mode === "start" || mode === "steer") {
    return mode;
  }
  throw new Error("mode must be auto, start, or steer");
}

View on GitHub (pinned to 01804a7531)

Solutions

  1. Pass max_stored_sessions as a JS number literal, not a string (e.g., 100, not "100").
  2. Ensure tool calls go through the Typebox-validated surface so the schema rejects bad types first.
  3. When calling via JSON RPC/MCP, encode the value as an unquoted JSON number.

Example fix

// before
codex_sessions_list({ max_stored_sessions: "100" })
// after
codex_sessions_list({ max_stored_sessions: 100 })
Defensive patterns

Strategy: validation

Validate before calling

function asOptionalInt(v: unknown, key: string): number | undefined {
  if (v === undefined || v === null) return undefined;
  if (typeof v !== "number" || !Number.isInteger(v)) {
    throw new Error(`${key} must be an integer`);
  }
  return v;
}

Type guard

const isOptionalInteger = (v: unknown): v is number =>
  typeof v === "number" && Number.isInteger(v);

Prevention

When it happens

Trigger: Calling codex_sessions_list with max_stored_sessions:'100' (string), 1.5 (float), true, or an object reaches this throw only if the value bypassed the Typebox schema (raw internal invocation, test seam, or an older MCP path).

Common situations: Invoking the tool outside the schema-validated agent-tool path; passing JSON where the value is a quoted string; programmatic callers that skip validation.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/b9eb013bed2d40d6. Report an issue: GitHub.