{"record":{"id":"4d72c60a02c3523e","repo":"ComposioHQ/composio","slug":"describetool-toolslug-expected-arguments-to-be","errorCode":null,"errorMessage":"${describeTool(toolSlug)} expected arguments to be an object, received ${actual}","messagePattern":"(.+?) expected arguments to be an object, received (.+?)","errorType":"exception","errorClass":"ComposioInvalidToolArgumentsError","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/utils/toolArguments.ts","lineNumber":66,"sourceCode":"    } 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}`\n  );\n}\n\nfunction describeTool(toolSlug?: string): string {\n  return toolSlug ? `Tool '${toolSlug}'` : 'Tool';\n}\n","sourceCodeStart":48,"sourceCodeEnd":74,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/utils/toolArguments.ts#L48-L74","documentation":"Thrown by assertPlainObject inside normalizeToolArguments when tool arguments are neither a plain object nor a JSON string that parses to one. After normalization the SDK requires a Record<string, unknown>; arrays, primitives, or null are rejected with the actual received type in the message.","triggerScenarios":"Calling executeTool with args[0] = [], 42, \"literal text\", null, or a JSON string like '\"hi\"' / '[1,2]' that parses to a non-object; also double-encoded strings like '\"{\\\"a\\\":1}\"'.","commonSituations":"Model emits a bare string or array as tool input; agent framework forwards positional args; tool schema expects object but caller passes a list of positional values.","solutions":["Pass a plain object matching the tool's inputParameters schema","If the caller supplies a JSON string, ensure it parses to an object (not array/scalar) and is not double-stringified","Catch ComposioInvalidToolArgumentsError and map it to a model-facing retry with the expected schema"],"exampleFix":"// before\nawait executeTool('foo', 'not json');\n// after\nawait executeTool('foo', { query: 'not json' });","handlingStrategy":"type-guard","validationCode":"function normalize(args: unknown): Record<string, unknown> | null { if (typeof args === 'string') { try { args = JSON.parse(args); } catch { return null; } } return (typeof args === 'object' && args !== null && !Array.isArray(args)) ? args as Record<string, unknown> : null; }","typeGuard":"const isPlainObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);","tryCatchPattern":"catch (e) { if (e instanceof ComposioInvalidToolArgumentsError) return { error: e.message }; throw e; }","preventionTips":["Match your argument shape to the tool's inputParameters schema","Beware double-encoded JSON strings","Reject arrays/primitives before calling executeTool"],"tags":["validation","tool-arguments","typescript"],"backgroundTag":"invalid-tool-arguments-type","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}