{"record":{"id":"50b3ba1cfb85605a","repo":"github/copilot-sdk","slug":"name-is-required-when-using-define-tool-with-handl","errorCode":null,"errorMessage":"name is required when using define_tool with handler=","messagePattern":"name is required when using define_tool with handler=","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/copilot/tools.py","lineNumber":314,"sourceCode":"                    _from_exception=True,\n                )\n\n        return Tool(\n            name=tool_name,\n            description=description or \"\",\n            parameters=schema,\n            handler=wrapped_handler,\n            overrides_built_in_tool=overrides_built_in_tool,\n            skip_permission=skip_permission,\n            defer=defer,\n            metadata=metadata,\n            is_terminal=is_terminal,\n        )\n\n    # If handler is provided, call decorator immediately\n    if handler is not None:\n        if name is None:\n            raise ValueError(\"name is required when using define_tool with handler=\")\n        return decorator(handler)\n\n    # If a parameter model is provided without a handler, expose a declaration-only tool.\n    if name is not None and params_type is not None:\n        schema = params_type.model_json_schema() if _is_pydantic_model(params_type) else None\n        return Tool(\n            name=name,\n            description=description or \"\",\n            parameters=schema,\n            handler=None,\n            overrides_built_in_tool=overrides_built_in_tool,\n            skip_permission=skip_permission,\n            defer=defer,\n            metadata=metadata,\n            is_terminal=is_terminal,\n        )\n\n    # Otherwise return decorator for @define_tool(...) usage","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/python/copilot/tools.py#L296-L332","documentation":"define_tool() builds a Tool registration helper. When a handler function is passed positionally via handler=, the SDK calls the decorator immediately, which requires a tool name; without one it raises this ValueError. Decorator-only usage (@define_tool() without handler) gets the name from the decorated function instead.","triggerScenarios":"Calling copilot.tools.define_tool(handler=my_func) or define_tool(params_type=..., handler=my_func) without passing name=; i.e. any immediate-invocation form that omits name.","commonSituations":"Migrating from a decorator style call to passing handler directly while forgetting name; dynamically registering tools from a config where the name key is missing; copying a @define_tool(params_type=Model) decorator example and adding handler= without adding name=.","solutions":["Pass name='my_tool' to define_tool when supplying handler=.","Or drop handler= and use define_tool as a decorator so the function name is inferred: @define_tool(name=None is allowed via @define_tool()).","If registering dynamically, validate the configured tool name exists before calling define_tool."],"exampleFix":"// before\ntool = define_tool(handler=search_docs, params_type=SearchParams)\n// after\ntool = define_tool(name='search_docs', handler=search_docs, params_type=SearchParams)","handlingStrategy":"validation","validationCode":"assert name and isinstance(name, str), 'define_tool requires name= when handler= is passed'","typeGuard":null,"tryCatchPattern":"try:\n    tool = define_tool(handler=fn, params_type=Model)\nexcept ValueError as exc:\n    if 'name is required' in str(exc):\n        tool = define_tool(name=fn.__name__, handler=fn, params_type=Model)\n    else:\n        raise","preventionTips":["Always pass name= when using the direct-call form with handler=.","Prefer the decorator form @define_tool() so the function name is inferred.","Validate dynamically configured tool names before registration.","Add a unit test per registered tool so a missing-name regression fails at test time."],"tags":["python","tools","valueerror","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}