{"record":{"id":"74b1a15cacc2f4ef","repo":"twentyhq/twenty","slug":"execute-tool-failed-for-name","errorCode":null,"errorMessage":"execute_tool failed for {name}","messagePattern":"execute_tool failed for (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/twenty-mcp-helper.const.ts","lineNumber":86,"sourceCode":"            # companies == {'records': [...], 'count': '5'}\n        \"\"\"\n        if not self._available:\n            raise RuntimeError('Twenty MCP bridge not available. Missing requests library or credentials.')\n\n        if name in self._MCP_NATIVE_TOOLS:\n            return self._raw_mcp_call(name, arguments)\n\n        wrapped = self._raw_mcp_call('execute_tool', {\n            'toolName': name,\n            'arguments': arguments or {},\n        })\n        # execute_tool returns one of:\n        #   success: { success: True,  message, result: {...} }\n        #   failure: { success: False, message, error }\n        # Raise on failure, unwrap on success, pass through unknown shapes.\n        if isinstance(wrapped, dict):\n            if wrapped.get('success') is False:\n                raise Exception(wrapped.get('error') or wrapped.get('message') or\n                                f\"execute_tool failed for {name}\")\n            if 'result' in wrapped:\n                return wrapped['result']\n        return wrapped\n\n    def bulk_upsert(self, plural: str, records: list, batch_size: int = 200):\n        \"\"\"\n        Upsert many records in batches, paginating to completion.\n\n        This is the recommended write path for imports: upsert dedupes on the\n        object's unique fields (e.g. email) server-side, so re-running a partial\n        or timed-out import is idempotent. Batches are capped at 200 (the platform\n        maximum); the loop runs entirely server-side so the agent never pays the\n        per-batch context cost.\n\n        Args:\n            plural: Plural object name, e.g. 'companies', 'people'.\n            records: List of record dicts to upsert.","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/twentyhq/twenty/blob/1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6/packages/twenty-server/src/engine/core-modules/tool/tools/code-interpreter-tool/twenty-mcp-helper.const.ts#L68-L104","documentation":"Raised by TwentyMCP.call_tool after it routes a catalog tool (anything not in the 4 MCP-native tools) through execute_tool and the JSON-RPC envelope comes back with success: False. The thrown message uses the envelope's error or message field if present, falling back to `execute_tool failed for <name>` only when both are missing. This indicates the inner workspace tool ran but reported a business-logic failure, not a transport error.","triggerScenarios":"Calling a workspace catalog tool (e.g. create_one_company, upsert_many_people) whose arguments fail server-side validation, violate a unique constraint, reference a non-existent relation id, or hit a permissions error for the token's workspace. The execute_tool envelope wraps that failure as { success: False, error/message: ... } and call_tool re-raises it.","commonSituations":"LLM-generated calls with wrong field names or types; upserting records that collide on a unique field without the right dedupe key; calling a tool the API token's user lacks permission for; passing a record id from a different workspace.","solutions":["Read the error/message field embedded in the exception text — it carries the inner tool's failure reason.","For unique-constraint failures, switch to the upsert_many_* tool so the server dedupes on the object's unique fields.","Validate argument shapes against the tool's schema (call `learn_tools` or inspect the catalog) before invoking.","Use bulk_upsert(plural, records) which catches per-batch exceptions and reports them in errors[] rather than aborting the whole import."],"exampleFix":"# before — single call aborts on the first bad record\nfor person in people:\n    twenty.call_tool('create_one_person', person)   # raises execute_tool failed for create_one_person\n# after — batched upsert dedupes and isolates per-batch failures\nsummary = twenty.bulk_upsert('people', people)\nif summary['failed']:\n    print('partial failure:', summary['errors'])","handlingStrategy":"retry","validationCode":"# Pre-validate argument shape against the catalog before calling.\nfrom typing import Any\n\ndef validate_args_against_catalog(catalog: dict, tool_name: str, args: dict) -> list[str]:\n    schema = catalog.get(tool_name, {}).get('inputSchema', {})\n    required = schema.get('required', [])\n    errors = []\n    for field in required:\n        if field not in args:\n            errors.append(f'{tool_name}: missing required field {field}')\n    return errors\n\n# usage:\ncatalog = twenty.call_tool('learn_tools', {})  # MCP-native, returns tool catalog\nerrs = validate_args_against_catalog(catalog, 'create_one_person', person)\nif errs:\n    raise ValueError(errs[0])","typeGuard":"from typing import Any\n\ndef is_execute_tool_failure(envelope: Any) -> bool:\n    return isinstance(envelope, dict) and envelope.get('success') is False","tryCatchPattern":"try:\n    rec = twenty.call_tool('create_one_company', company)\nexcept Exception as e:\n    msg = str(e)\n    if 'execute_tool failed' in msg:\n        # business-logic failure from the inner tool — do NOT blind-retry; fix args\n        if 'unique' in msg.lower() or 'duplicate' in msg.lower():\n            rec = twenty.call_tool('upsert_one_company', company)  # switch to upsert to dedupe\n        else:\n            raise\n    else:\n        raise","preventionTips":["Prefer bulk_upsert(plural, records) for writes — it isolates per-batch failures instead of aborting on the first error.","Call learn_tools once and cache the catalog; validate argument shapes against each tool's inputSchema before invoking.","Resolve relation ids via lookup_by before writing so create/update calls reference valid ids."],"tags":["python","code-interpreter","mcp","workspace-tools","api-error"],"backgroundTag":null,"analyzedSha":"1f5dd2bbd2a8da3419c8cfd52dd545c0024df1a6","analyzedAt":"2026-08-12T15:37:27.593Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}