Skip to content

[BUG] DeepSeek API Strict Mode Returns Malformed JSON in Function Call Arguments with Schema #1069

@Forence1999

Description

@Forence1999

[BUG] DeepSeek API Strict Mode Returns Malformed JSON in Function Call Arguments

Describe the bug

When using strict: true in the function/tool definition with DeepSeek API (beta endpoint), the API returns malformed JSON in the function.arguments field. Specifically, the first property key is missing its closing double quote, making the JSON unparseable.

Example of malformed response:

{"selected: ["A", "C", "D"]}

Instead of the expected valid JSON:

{"selected": ["A", "C", "D"]}

This causes json.loads() to fail with:

JSONDecodeError: Expecting ':' delimiter: line 1 column 15 (char 14)

To Reproduce

Minimal Reproducible Code

from openai import OpenAI

# Initialize client with beta endpoint
client = OpenAI(
    api_key="<your-api-key>",
    base_url="https://api.deepseek.com/beta"
)

# Define tool with strict=True
tools = [{
    "type": "function",
    "function": {
        "name": "submit_answer",
        "description": "Submit multiple choice answer",
        "strict": True,  # ← This triggers the bug
        "parameters": {
            "type": "object",
            "properties": {
                "selected": {
                    "type": "array",
                    "description": "Selected options",
                    "items": {"type": "string"}
                }
            },
            "required": ["selected"],
            "additionalProperties": False
        }
    }
}]

# Send request
response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[{
        "role": "user",
        "content": "Which are Python core features? A. Dynamic typing B. Compiled language C. OOP D. Multithreading. Use submit_answer tool."
    }],
    tools=tools,
    tool_choice="auto"
)

# Try to parse the arguments
import json
arguments_raw = response.choices[0].message.tool_calls[0].function.arguments
print(f"Raw arguments: {arguments_raw}")

# This will fail with JSONDecodeError
args = json.loads(arguments_raw)  # ❌ Crashes here

Steps to reproduce:

  1. Use DeepSeek API with /beta endpoint
  2. Define a function/tool with strict: true
  3. Include additionalProperties: false in parameters schema
  4. Make an API call that triggers function calling
  5. Attempt to parse the returned function.arguments as JSON

Expected behavior

The API should return valid JSON in function.arguments that can be parsed with standard JSON parsers:

{
  "selected": ["A", "C", "D"]
}

Screenshots

Comparison Test Results

Test Code:

def test_strict_mode(strict: bool):
    tools = [{
        "type": "function",
        "function": {
            "name": "submit_answer",
            "strict": strict,  # Test with True/False
            "parameters": {
                "type": "object",
                "properties": {
                    "selected": {
                        "type": "array",
                        "items": {"type": "string"}
                    }
                },
                "required": ["selected"],
                "additionalProperties": False
            }
        }
    }]
    # ... rest of the code

Output:

======================================================================
Testing with strict=False
======================================================================

✓ Tool Called: submit_answer
  Arguments (raw): {"selected": ["A", "C", "D"]}
  ✅ JSON Valid
  Selected: ['A', 'C', 'D']

======================================================================
Testing with strict=True
======================================================================

✓ Tool Called: submit_answer
  Arguments (raw): {"selected: ["A", "C", "D"]}
  ❌ JSON Invalid: Expecting ':' delimiter: line 1 column 15 (char 14)
  Error Position: char 14
  Context: ...lected: ["A", "C", "...

Key Observation: The only difference between the two tests is strict: True vs strict: False. With strict=True, the closing quote is missing after "selected.

Additional context

Environment

  • API Endpoint: https://api.deepseek.com/beta
  • Model: deepseek-chat
  • SDK: OpenAI Python SDK (official)
  • Python Version: 3.12.11
  • Date Tested: 2025-12-28

Impact

  • Severity: High - Completely breaks function calling when using strict mode
  • Workaround: Disable strict: true (use strict: false or omit the parameter)
  • Affected Use Cases: Any application relying on structured output validation via strict mode

Additional Notes

  1. This issue is specific to the /beta endpoint
  2. The same tool definition works correctly when strict: false (default)
  3. Tested with the official OpenAI SDK (not third-party wrappers like LiteLLM)
  4. The malformed JSON always has the same pattern: missing closing quote on the first property key

Related

  • Similar to function calling issues seen in other LLM APIs, but this is specifically triggered by the strict parameter
  • DeepSeek's strict mode is meant to enforce schema compliance (similar to OpenAI's structured outputs), but the implementation appears to have a JSON serialization bug

Let me know if you need the complete test scripts or additional reproduction details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions