Skip to content

[BUG] DeepSeek models (V3/R1/V4 Flash/Pro) exhibit 5 structural tool-calling defects: Missing Required Params (Strict Mode), Draft 2020-12 violations, reasoning_content loss, XML fallback missing, parallel ordering mismatch. #547

Open

Description

@myk1yt

DeepSeek Tool Calling Compatibility Issues — Zoo Code Bug Report

Roo Code References: #12195 #12196 #10320 #10325 #11804 #11191 #10171

Hello. I could have left this on Discord, but I thought it would be better to post it here.

I have been using DeepSeek V4 Pro and Flash, and I have compiled the issues that occurred during tool invocation from the error logs I've been tracking.

Personally, I have resolved these by using the VibeZoo MCP tool I created to address my own inconveniences. However, as this is merely a stopgap measure, I am posting this because I believe it would be better to fundamentally resolve the issue within the Zoo Code itself.

I have requested that the categorization of the problem types and the details of the issues be written in Zoo Code.

Problem

Zoo Code tool schemas and message serialization are not fully compatible with DeepSeek API requirements. Five distinct issues cause HTTP 400/422 errors, infinite retry loops, agent deadlocks, and regex validation failures across the entire tool calling pipeline (schema compilation -> message serialization -> stream parsing -> result aggregation). Users cannot complete multi-step tasks without repeated failures.

Context

All Zoo Code users with DeepSeek V3, R1, V4 Flash, or V4 Pro as LLM backend. Also affects users routing through OpenRouter/Cerebras proxies enforcing Draft 2020-12. Issues manifest on every conversation involving tool calls, especially multi-turn or parallel execution scenarios. Each defect affects specific models (see table below).

Reproduction Steps

  1. Set LLM provider to any DeepSeek model (V4 Flash/Pro recommended for full reproduction)
  2. Start a conversation and request a task requiring tool calls (file read, code search, etc.)
  3. Observe behavior across multiple turns and parallel tool executions
  4. Each of the 5 defects will surface depending on the specific operation:
    • Defect 1: Any call with optional params (read_file limit/offset)
    • Defect 2: Schema compilation at conversation start (OpenRouter/Cerebras)
    • Defect 3: Follow-up question after first assistant reply
    • Defect 4: Complex tasks under high context pressure (10+ turns)
    • Defect 5: Any parallel tool execution (2+ simultaneous calls)

Expected Result

All 5 defects resolved: Zoo Code tool schemas compile cleanly under Draft 2020-12, reasoning_content is preserved across turns, XML fallback is parsed, and parallel results are ordered correctly.

Actual Result

5 separate failures: (1) Infinite retry on optional params, (2) HTTP 422 schema compilation error, (3) HTTP 400 reasoning_content missing, (4) Agent deadlock on XML output, (5) HTTP 400 tool result ordering mismatch.

Variations Tried

  • Switching strict:true to strict:false -> fixes Defect 1 but breaks Draft 2020-12 compliance (Defect 2)
  • Disabling parallel tool calling -> fixes Defect 5 but severely degrades performance
  • Adding system prompt enforcing JSON format -> reduces Defect 4 frequency but does not eliminate
  • Manual schema keyword removal -> works but requires per-tool maintenance

App Version

Zoo Code v3.58.1 (Roo Code fork). Affected core files: base-provider.ts, json-schema.ts, openai-format.ts, openai.ts, deepseek.ts, Task.ts, parse-assistant-message.ts, cerebras.ts, r1-format.ts.


Relevant logs or errors (optional)

Detailed Defect Breakdown

# Defect Error Stage Priority Affected Models
1 Missing Required Parameters Infinite retry / Missing required parameter Schema validation P0 V4 Pro, V4 Flash
2 Draft 2020-12 Violation HTTP 422 strict mode violation Schema compilation P0 V4 Pro, V4 Flash, R1
3 reasoning_content State Loss HTTP 400 must be passed back Message serialization P0 V4 Pro, R1 (reasoner)
4 XML Tag Fallback Missing model did not call any tools Stream parsing P1 R1, V4 Pro (under load)
5 Parallel Ordering Mismatch HTTP 400 ordering mismatch Result aggregation P1 V4 Pro, V4 Flash, R1

Defect 1: Missing Required Parameters

  • Key Error: Missing required parameter infinite retry
  • Scenario: Model omits optional params (limit, offset) under strict:true -> infinite retry loop
  • What DeepSeek did: Called read_file({"path": "file.txt"}) WITHOUT limit/offset (they are optional)
  • Why wrong: Draft 2020-12 forces ALL properties into required array. API rejects.
  • Fix: base-provider.ts - Wrap optional params with anyOf + null to preserve optional semantics

Defect 2: Draft 2020-12 Violation

  • Key Error: HTTP 422 strict mode violation
  • Scenario: Schema contains pattern/regex, minLength -> gateway rejects compilation
  • What DeepSeek did: Sent schema with "pattern": "[a-zA-Z0-9_]+$" for search_files (regex validation)
  • Why wrong: Draft 2020-12 Strict Mode FORBIDS pattern, minLength, minItems keywords
  • Fix: json-schema.ts - normalizeToolSchema() strips forbidden keywords, converts multi-type to anyOf

Defect 3: reasoning_content State Loss

  • Key Error: HTTP 400 "The reasoning_content must be passed back"
  • Scenario: 2nd+ turn -> previous reasoning_content missing -> HTTP 400
  • What DeepSeek did: Returned reasoning_content in turn 1. Zoo Code sent turn 2 WITHOUT it.
  • Why wrong: convertToOpenAiMessages() drops reasoning_content. DeepSeek requires it at root level.
  • Fix: openai-format.ts - Add preserveReasoningContent + addEmptyReasoning options

Defect 4: XML Tag Fallback Missing

  • Key Error: model did not call any required tools
  • Scenario: Under load, model outputs <read_file> XML in plain text -> agent deadlock
  • What DeepSeek did: Outputted XML tags like <read_file>src/config.ts</read_file> instead of JSON tool_calls
  • Why wrong: Native mode has XML detection disabled. XML treated as regular text.
  • Fix: Task.ts - Hybrid XML Interceptor promotes XML blocks to Native ToolCall format

Defect 5: Parallel Ordering Mismatch

  • Key Error: HTTP 400 tool results ordering mismatch
  • Scenario: Parallel calls -> async completion order != call order -> HTTP 400
  • What DeepSeek did: Called [search_files, read_file] in parallel. read_file completed first (fast I/O).
  • Why wrong: Zoo Code sends results in completion order, not call order. API requires exact match.
  • Fix: Task.ts - Sort Barrier: capture ID order, Promise.all(), sort by ID before persisting

This report was prepared by Zoo (VP) for the Zoo Code Dev Team.

Activity

  1. Keesan12 commented on Jun 9, 2026

    @Keesan12

    This is a really useful breakdown. The part I would try to preserve in the fix is the boundary map: schema compilation, message serialization, stream parsing, and result aggregation are different failure planes, even if they all show up to the user as "the agent got stuck again."

    A pattern that has helped us on similar agent/tooling failures:

    • add one fixture per boundary, not one giant end-to-end fixture
    • make the failure class typed enough that the runner knows what changed before retrying
    • for parallel tool calls, keep the original call-order IDs as the source of truth and treat completion order as just transport noise
    • for optional params under strict schemas, normalize once at provider-boundary time rather than sprinkling provider exceptions through every tool

    The practical lesson we keep relearning is that retries are expensive when the system can't prove the next attempt is different. We baked a lot of that into MartinLoop recently: typed blockers, proof-before-retry, and run receipts so the agent doesn't just politely repeat the same miss.

    If you end up testing against real traces from DeepSeek/OpenRouter/Cerebras, I'd be interested in comparing notes. Also, if MartinLoop's loop-control angle is useful to this crowd, feedback/support there would genuinely help us aim it at the right failures instead of building in a vacuum.

  2. myk1yt commented on Jun 10, 2026

    @myk1yt
    ContributorAuthor

    Zoo Code + DeepSeek: Making Error Messages LLM-Friendly (Self-Correction System)


    I spent time working with Zoo to solve this problem. I had been gradually fixing the error messages and issues to fit my personal usage environment. Then I needed to install Zoo Code on a new computer, and all my settings were gone. So I invested focused time to restore my setup as close to the original as possible. Along the way, I decided that the error messages I had always glossed over also needed some attention.

    Because I use DeepSeek, it would have been easy to only fix issues for DeepSeek. But Zoo Code is an open tool that works with all APIs — it should be resilient even when other LLMs produce errors. Looking at the Discord community, the Zoo Code developers are talented and kind, but since it's not a commercial product, they can't address every possible error. Neither can I.

    So I decided: let's make error messages LLM-friendly instead. Let today's intelligent LLMs be resilient on their own. That's how we reached this conclusion.

    Ensuring that error messages do not appear is something that the highly competent Zoo Code development team will handle later, but for me, proceeding with the work quickly and accurately is more important.

    Besides, I might end up using other APIs apart from DeepSeek, and they will probably all trigger errors while making different tool calls.


    <Below is the technical report written by Zoo (Vice President)>

    Problem

    Zoo Code v3.58.1 + DeepSeek-v4-flash / Pro produces 6 tool-calling error types:

    Error Root Cause
    Artifact not found: "cmd-1749642304740.txt" AI hallucinated a non-existent artifact ID for read_command_output
    HTTP 422 strict mode violation Schema contains pattern/minLength — forbidden in Draft 2020-12
    Missing required parameter Strict mode treats optional fields as required
    HTTP 400 reasoning_content must be passed back Zoo Code drops reasoning_content between turns
    model did not call any tools AI outputs XML instead of JSON tool calls
    HTTP 400 tool results ordering mismatch Results returned in completion order, not call order

    The common thread: error messages only describe what failed, not what context the AI needs to self-correct.

    Approach: Context-Rich Errors → AI Self-Correction

    Instead of hardcoding specific instructions (fragile, model-specific), we added operational context to error messages so the LLM can figure out alternatives on its own.

    Principle

    "Tell the AI what is wrong, not what to do. Let the LLM's intelligence find the best alternative."

    Examples

    Before (context-free) After (context-rich)
    "Artifact not found: ID." "Artifact not found: ID. Available artifacts: [real_IDs]. This ID was never generated."
    "Missing required parameter 'limit'" "Parameter 'limit' was expected but is optional. Strict-mode may cause this. It can be omitted."
    "HTTP 422 strict mode violation" "Schema validation failed: 'pattern' keyword not allowed in Draft 2020-12. Alternate approaches may work."

    Typed Blockers (Phase 2)

    Added machine-readable error type prefixes:

    Blocker Applied To
    [SCHEMA_ERROR] Schema validation failures (Defect 1, 2)
    [PARSE_ERROR] Response parsing failures (Defect 4a, 4b, 4c)
    [RESOURCE_ERROR] Resource lookup failures (Artifact hallucination)

    Auto-Recovery (Defect 3, 5)

    Some errors need no LLM involvement:

    • Defect 3: reasoning_content auto-preserved between turns
    • Defect 5: Results auto-sorted by tool_use_id

    Verification

    Test Result
    read_command_output("fake-ID") → [RESOURCE_ERROR] + available list ✅
    AI self-correction: reads available list → retries with correct ID ✅ Success
    findstr "[SCHEMA_ERROR]" ✅ 2 occurrences
    findstr "[PARSE_ERROR]" ✅ 3 occurrences
    findstr "[RESOURCE_ERROR]" ✅ 1 occurrence
    VS Code reload + all tool calls ✅ No errors
  3. feigou6545456 commented on Jun 30, 2026

    @feigou6545456

    我想关心何时修复,谢谢

  4. houleixx commented on Jul 1, 2026

    @houleixx

    For a compatibility matrix like this, request-level evidence helps a lot.

    ccglass can capture OpenAI-compatible requests/responses and show tool schemas, strict-mode payloads, raw model output, tool_calls, reasoning_content, token usage, and provider errors.

    Project: https://github.com/jianshuo/ccglass

    It may help produce smaller repros for each DeepSeek defect and verify whether the issue is model output, provider adapter behavior, or client-side parsing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions