From 94d764d8fa9cb92831b4d79f2750f9cbedd44af0 Mon Sep 17 00:00:00 2001 From: Lex Oleksiienko Date: Fri, 15 May 2026 21:48:49 -0600 Subject: [PATCH] fix(sdk): pass [] instead of None for allowed/disallowed tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When DISABLE_TOOL_VALIDATION=true, ClaudeSDKManager was passing None for allowed_tools and disallowed_tools. The downstream claude-agent-sdk (versions 0.1.x through at least 0.2.82) calls `list(self._options.allowed_tools)` unconditionally in `subprocess_cli.py:_apply_skills_defaults` and crashes with "TypeError: 'NoneType' object is not iterable" before the CLI process even starts. Symptom: every Telegram message produces "Claude integration failed". This patches the symptom in Cct by passing empty lists. The CLI treats an empty list the same as "no --allowedTools flag" → no restriction, which is the intent of DISABLE_TOOL_VALIDATION=true. Filed upstream as well: https://github.com/anthropics/claude-agent-sdk-python (pending). Repro: set DISABLE_TOOL_VALIDATION=true + ENABLE_MCP=true in .env, send any message. SDK never returns past ClaudeSDKClient.connect(). Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 6 +++++- src/claude/sdk_integration.py | 12 ++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 6e3390e3a..7d851b760 100644 --- a/.gitignore +++ b/.gitignore @@ -146,4 +146,8 @@ data/ sessions/ backups/ uploads/ -config/mcp.json \ No newline at end of file +config/mcp.json +# Local env backups (ignored) +.env.bak +.env.bak2 +.env.kai diff --git a/src/claude/sdk_integration.py b/src/claude/sdk_integration.py index 5a95f16da..dce9fdd74 100644 --- a/src/claude/sdk_integration.py +++ b/src/claude/sdk_integration.py @@ -309,11 +309,15 @@ def _stderr_callback(line: str) -> None: path=str(claude_md_path), ) - # When DISABLE_TOOL_VALIDATION=true, pass None for allowed/disallowed - # tools so the SDK does not restrict tool usage (e.g. MCP tools). + # When DISABLE_TOOL_VALIDATION=true, pass [] (not None) for + # allowed/disallowed tools. claude-agent-sdk subprocess_cli.py + # calls list(options.allowed_tools) unconditionally and crashes + # with "'NoneType' object is not iterable". Empty list is treated + # by the CLI as "no --allowedTools flag" → no restriction, which + # is the intent of DISABLE_TOOL_VALIDATION=true. if self.config.disable_tool_validation: - sdk_allowed_tools = None - sdk_disallowed_tools = None + sdk_allowed_tools = [] + sdk_disallowed_tools = [] else: sdk_allowed_tools = self.config.claude_allowed_tools sdk_disallowed_tools = self.config.claude_disallowed_tools