Skip to content

[BUG] create_agent fails with Pydantic validation error when LLM passes skills as JSON string instead of list #770

Description

@jinglun010-cpu

Bug Description

When using certain LLM providers (specifically qwen3.7-max via Alibaba DashScope OpenAI-compatible endpoint), the create_agent and load_skill tools fail with a Pydantic validation error because the model passes the skills parameter as a JSON-encoded string ('["sql_injection"]') instead of an actual JSON array (["sql_injection"]).

This causes all create_agent calls to fail, preventing the agent from spawning specialist child agents for parallel testing. The agent falls back to serial execution and often gets stuck browsing Caido proxy history instead of actively testing.

Error Message

Tool create_agent failed
An error occurred while running the tool. Please try again. Error: Invalid JSON input for tool create_agent: 1 validation error for create_agent_args
skills
  Input should be a valid list [type=list_type, input_value='["sql_injection"]', input_type=str]
    For further information, visit https://errors.pydantic.dev/2.13/v/list_type

The same error occurs for load_skill:

Invalid JSON input for tool load_skill: 1 validation error for load_skill_args
skills
  Input should be a valid list [type=list_type, input_value='["xss"]', input_type=str]

Steps to Reproduce

  1. Configure Strix with qwen3.7-max via DashScope (OpenAI-compatible endpoint):
    // ~/.strix/cli-config.json
    {
      "env": {
        "STRIX_LLM": "openai/qwen3.7-max",
        "LLM_API_BASE": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "LLM_API_KEY": "sk-..."
      }
    }
  2. Run a scan that triggers create_agent:
    strix --target http://example.com --instruction "Use create_agent to spawn a SQL injection specialist with skills=[\"sql_injection\"]"
  3. Observe in strix.log that every create_agent call fails:
    DEBUG openai.agents: Invoking tool create_agent
    DEBUG openai.agents: Tool create_agent failed
    
  4. Check agents.db (SQLite) to confirm the error is a Pydantic validation failure on the skills parameter.

Root Cause

The skills parameter is typed as list[str] in both create_agent and load_skill. When the LLM provider serializes function call arguments, some providers (notably qwen3.7-max via DashScope) pass array-typed parameters as JSON-encoded strings rather than native JSON arrays. Pydantic's strict validation then rejects the string input before the function body executes.

This is a provider compatibility issue — the same LLM model works correctly for scalar parameters (strings, booleans) but fails for array parameters.

Environment

  • OS: Windows 11
  • Strix Version: 1.0.4 (also confirmed present in v1.1.0 source)
  • Python Version: 3.13
  • LLM Used: qwen3.7-max via Alibaba DashScope (OpenAI-compatible mode)

Impact

  • Severity: High — completely breaks multi-agent orchestration
  • Agent cannot spawn specialist child agents (SQL injection tester, XSS specialist, etc.)
  • Falls back to serial execution, significantly reducing test coverage
  • In our penetration test of a ZDNS DDI appliance, this caused 3 out of 6 scan runs to produce zero vulnerability findings because the agent never executed injection payloads

Proposed Fix

We have a working fix that adds type tolerance for string-encoded arrays:

  1. Widen the type annotation: skills: list[str] -> skills: str | list[str]
  2. Add strict_mode=False to the @function_tool decorator
  3. Parse string inputs in the function body:
    if isinstance(skills, str):
        try:
            skills = json.loads(skills)
        except json.JSONDecodeError:
            skills = [s.strip() for s in skills.split(",") if s.strip()]

This fix has been tested and verified: after applying it, create_agent successfully spawns child agents that execute 23+ exec_command calls for SQL injection testing.

Files to fix:

  • strix/tools/agents_graph/tools.py (create_agent)
  • strix/tools/load_skill/tool.py (load_skill)

We will submit a PR with this fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions