openclaw/openclaw · error
Codex settled-turn projection requires object tool arguments
Error message
Codex settled-turn projection requires object tool arguments
What it means
Thrown by serializeToolArguments when tool arguments were supplied as a string, JSON.parse succeeded, but the parsed value is not a record object (e.g. an array, number, string, boolean, or null). Codex function_call arguments must serialize to a JSON object, so a JSON string that parses to a non-object is rejected even though it is valid JSON.
Source
Thrown at extensions/codex/src/app-server/settled-turn-projection.ts:76
function requireToolName(value: unknown): string {
const name = readNonEmptyString(value);
if (!name || !TOOL_NAME_PATTERN.test(name)) {
throw new Error("Codex settled-turn projection found an invalid tool name");
}
return name;
}
function serializeToolArguments(value: unknown): string {
if (typeof value === "string") {
let parsed: unknown;
try {
parsed = JSON.parse(value);
} catch {
throw new Error("Codex settled-turn projection found invalid JSON tool arguments");
}
if (!isRecord(parsed)) {
throw new Error("Codex settled-turn projection requires object tool arguments");
}
return requireBoundedText(value, "tool arguments");
}
if (!isRecord(value)) {
throw new Error("Codex settled-turn projection requires object tool arguments");
}
let serialized: string;
try {
serialized = JSON.stringify(value);
} catch {
throw new Error("Codex settled-turn projection found unserializable tool arguments");
}
return requireBoundedText(serialized, "tool arguments");
}
function projectUserMessage(message: AgentMessage): JsonValue[] {
const record = message as unknown as Record<string, unknown>;
const upstreamUserText = readUpstreamUserText(message);View on GitHub (pinned to 01804a7531)
Solutions
- Inspect the parsed value of arguments to see its actual type.
- Ensure the toolCall producer builds arguments as a plain object {} and JSON.stringify it.
- If the upstream legitimately uses positional args, wrap them as { args: [...] } at the adapter.
Example fix
// before
{ type: "toolCall", id, name, arguments: JSON.stringify([1, 2, 3]) } // parses to array -> throws
// after
{ type: "toolCall", id, name, arguments: JSON.stringify({ args: [1, 2, 3] }) } Defensive patterns
Strategy: validation
Validate before calling
function isJsonObjectArgumentsString(value: unknown): boolean {
if (typeof value !== "string") return false;
try {
const parsed = JSON.parse(value);
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
} catch {
return false;
}
}
// at the producer
if (typeof args === "string") {
const parsed = JSON.parse(args);
if (Array.isArray(parsed) || typeof parsed !== "object" || parsed === null) {
args = JSON.stringify({ value: parsed });
}
} Type guard
function parsesToJsonObject(value: unknown): boolean {
if (typeof value !== "string") return false;
try {
const p = JSON.parse(value);
return typeof p === "object" && p !== null && !Array.isArray(p);
} catch {
return false;
}
} Prevention
- Never JSON.stringify arrays or scalars into arguments; wrap them as { value: ... }.
- Validate string arguments parse to a plain object at the adapter.
- Prefer passing arguments as an object literal and let the projection serialize.
When it happens
Trigger: arguments is the string "[1,2,3]" (parses to array), "42" (number), "\"text\"" (string), "null", or "true"; a provider that stringified a non-object value as arguments.
Common situations: Provider adapter that stringified a positional-arguments array instead of a named-args object; a model that returned a bare scalar as arguments; test fixture using JSON.stringify on a non-object.
Related errors
- Codex settled-turn projection found invalid JSON tool argume
- Codex settled-turn projection found unserializable tool argu
- Codex settled-turn projection found oversized ${label}
- Codex settled-turn projection found empty ${label}
- Codex settled-turn projection found an invalid tool call id
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/6364abadc350e213.
Report an issue: GitHub.