{"record":{"id":"107d865366a2c695","repo":"github/copilot-sdk","slug":"on-permission-request-must-be-callable-when-provid","errorCode":null,"errorMessage":"on_permission_request must be callable when provided.","messagePattern":"on_permission_request must be callable when provided\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/copilot/client.py","lineNumber":2531,"sourceCode":"            A :class:`CopilotSession` instance for the new session.\n\n        Raises:\n            ValueError: If ``on_permission_request`` is provided but not callable.\n\n        Example:\n            >>> session = await client.create_session(\n            ...     on_permission_request=PermissionHandler.approve_all,\n            ... )\n            >>>\n            >>> # Session with model and streaming\n            >>> session = await client.create_session(\n            ...     on_permission_request=PermissionHandler.approve_all,\n            ...     model=\"gpt-4\",\n            ...     streaming=True,\n            ... )\n        \"\"\"\n        if on_permission_request is not None and not callable(on_permission_request):\n            raise ValueError(\"on_permission_request must be callable when provided.\")\n        if github_token is not None and github_token_provider is not None:\n            raise ValueError(\"github_token and github_token_provider are mutually exclusive\")\n        if ask_user_variant not in (None, \"legacy\", \"elicitation\"):\n            raise ValueError('ask_user_variant must be \"legacy\" or \"elicitation\"')\n        if not self._client:\n            await self.start()\n\n        tool_defs = []\n        if tools:\n            for tool in tools:\n                definition: dict[str, Any] = {\n                    \"name\": tool.name,\n                    \"description\": tool.description,\n                }\n                if tool.parameters:\n                    definition[\"parameters\"] = tool.parameters\n                if tool.overrides_built_in_tool:\n                    definition[\"overridesBuiltInTool\"] = True","sourceCodeStart":2513,"sourceCodeEnd":2549,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/python/copilot/client.py#L2513-L2549","documentation":"start_session() validates its keyword arguments before creating a session. If `on_permission_request` is supplied it must be a callable (an async or sync handler invoked for permission prompts); passing a non-callable such as a string, bool, or None-like sentinel raises this ValueError immediately. This is fail-fast argument validation to prevent a broken callback surfacing later mid-session.","triggerScenarios":"Calling `client.start_session(on_permission_request=\"approve_all\")` or passing a class/method object that isn't bound-callable, a constant, or a wrongly-named attribute.","commonSituations":"Passing the docstring-style value instead of `PermissionHandler.approve_all`; passing a decorated function that returned a non-callable; mixing up argument order so a string lands in on_permission_request.","solutions":["Pass an actual callable, e.g. `on_permission_request=PermissionHandler.approve_all` or your own `async def handler(req): ...`.","Pass None (or omit) if you don't want a permission handler.","Add a `callable(handler)` check at your config layer before constructing the session."],"exampleFix":"// before\nawait client.start_session(on_permission_request=\"approve_all\")\n// after\nawait client.start_session(on_permission_request=PermissionHandler.approve_all)","handlingStrategy":"validation","validationCode":"if on_permission_request is not None and not callable(on_permission_request):\n    raise TypeError(\"on_permission_request must be callable or None\")","typeGuard":"def is_permission_handler(value) -> bool:\n    return value is None or callable(value)","tryCatchPattern":"try:\n    session = await client.start_session(on_permission_request=handler)\nexcept ValueError as e:\n    if \"on_permission_request\" in str(e):\n        raise ConfigError(\"permission handler must be a callable\") from e\n    raise","preventionTips":["Always pass bound methods or functions, e.g. PermissionHandler.approve_all","Validate handler config with callable() before session creation","Avoid stringly-typed handler names in config — resolve them to callables first"],"tags":["python","argument-validation","permissions","callback"],"backgroundTag":"invalid-argument-value","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}