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
- Pass max_stored_sessions as a JS number literal, not a string (e.g., 100, not "100").
- Ensure tool calls go through the Typebox-validated surface so the schema rejects bad types first.
- 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
- Always pass integers as JS numbers, not strings.
- Let the Typebox schema validate inputs before tool execute runs.
- For JSON transports, encode numbers without quotes.
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
- ${key} must be between 1 and 1000
- mode must be auto, start, or steer
- Codex image understanding requires model id.
- Codex structured extraction requires model id.
- Codex structured extraction requires instructions.
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/b9eb013bed2d40d6.
Report an issue: GitHub.