{"record":{"id":"d680f1fdb2343891","repo":"ComposioHQ/composio","slug":"describetool-toolslug-received-arguments-as-a","errorCode":null,"errorMessage":"${describeTool(toolSlug)} received arguments as a string that is not valid JSON","messagePattern":"(.+?) received arguments as a string that is not valid JSON","errorType":"exception","errorClass":"ComposioInvalidToolArgumentsError","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/utils/toolArguments.ts","lineNumber":49,"sourceCode":" * @param toolSlug - Optional tool slug, used to enrich the error message.\n * @returns The normalized arguments as a `Record<string, unknown>`.\n */\nexport function normalizeToolArguments(input: unknown, toolSlug?: string): Record<string, unknown> {\n  if (input === null || input === undefined) {\n    return {};\n  }\n\n  if (typeof input === 'string') {\n    const trimmed = input.trim();\n    if (trimmed === '') {\n      return {};\n    }\n\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(trimmed);\n    } catch (cause) {\n      throw new ComposioInvalidToolArgumentsError(\n        `${describeTool(toolSlug)} received arguments as a string that is not valid JSON`,\n        { cause: cause instanceof Error ? cause : undefined }\n      );\n    }\n    return assertPlainObject(parsed, toolSlug);\n  }\n\n  return assertPlainObject(input, toolSlug);\n}\n\nfunction assertPlainObject(value: unknown, toolSlug?: string): Record<string, unknown> {\n  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n    return value as Record<string, unknown>;\n  }\n\n  const actual = Array.isArray(value) ? 'array' : typeof value;\n  throw new ComposioInvalidToolArgumentsError(\n    `${describeTool(toolSlug)} expected arguments to be an object, received ${actual}`","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/toolArguments.ts#L31-L67","documentation":"Thrown by normalizeToolArguments when the model (or caller) passes tool arguments as a string that fails JSON.parse. Composio tolerates models that emit stringified JSON (issue #2406), but the string must still be syntactically valid JSON; a parse failure raises ComposioInvalidToolArgumentsError with the original SyntaxError as cause.","triggerScenarios":"Calling executeTool (directly or via provider wrapTool/executeTool paths) with args[0] as a string like \"{'foo': 1}\" (single quotes), truncated JSON, or text with a leading BOM/whitespace-only content prefixed non-JSON.","commonSituations":"LLM emits malformed JSON tool calls (unquoted keys, trailing commas, single quotes); proxy or agent framework concatenates arguments; string built by template literal with unescaped quotes.","solutions":["Inspect the raw arguments string before calling the tool and log it when JSON.parse fails","If the model output is reliably non-JSON, repair it upstream (e.g. jsonrepair, or instruct the model with stricter tool-call formatting)","Catch ComposioInvalidToolArgumentsError and re-prompt the model with the parse error so it re-emits valid JSON","Ensure you pass an object, not JSON.stringify-ed arguments, when you already control the call"],"exampleFix":"// before\nawait executeTool('foo', \"{'path': './a'}\");\n// after\nawait executeTool('foo', { path: './a' });","handlingStrategy":"validation","validationCode":"const args = typeof raw === 'string' ? raw : JSON.stringify(raw ?? '');\nlet parsed: unknown;\ntry { parsed = JSON.parse(args); } catch { /* repair or reject before calling executeTool */ }","typeGuard":"function isJsonObject(s: string): boolean { try { const v = JSON.parse(s); return typeof v === 'object' && v !== null && !Array.isArray(v); } catch { return false; } }","tryCatchPattern":"try { await executeTool(slug, args); } catch (e) { if (e instanceof ComposioInvalidToolArgumentsError) { /* re-prompt model with e.message */ } throw e; }","preventionTips":["Always pass plain objects to executeTool when you control the call","Log the raw argument string on failure to spot model formatting bugs","Use structured outputs / strict tool-call mode in your model provider"],"tags":["json","tool-arguments","validation","typescript"],"backgroundTag":"invalid-json-tool-arguments","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}