DEV Community

ZAKARIA KHCHICHE
ZAKARIA KHCHICHE

Posted on

An OpenAI tool Mistral rejected: the SDK's strict: null

TL;DR: mistral-common's Function.from_openai rejected any tool definition containing "strict": null. That is exactly what the OpenAI SDK produces by default when you dump a tool. My fix (PR #396) was merged by the Mistral AI maintainers on October 21, 2026, and will ship in the next release after 1.12.0. Until then, there is a one-line workaround (below).

The symptom

You are moving agents from OpenAI to Mistral, or running an OpenAI-compatible gateway in front of Mistral models. Your tools are typed with the OpenAI SDK, then converted by mistral-common:

from openai.types.shared import FunctionDefinition
from mistral_common.protocol.instruct.tool_calls import Function

tool = FunctionDefinition(name="get_weather", parameters={"type": "object"})
Function.from_openai(tool.model_dump())
Enter fullscreen mode Exit fullscreen mode

On mistral-common 1.12.0:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Function
strict
  Input should be a valid boolean [type=bool_type, input_value=None, input_type=NoneType]
Enter fullscreen mode Exit fullscreen mode

The tool is valid. Tool.from_openai and ChatCompletionRequest.from_openai(tools=...) fail the same way, because they call the same function.

The cause

In the OpenAI schema, strict is optional and nullable, so the SDK dumps it as None when you don't set it:

{'name': 'get_weather', 'description': None, 'parameters': {'type': 'object'}, 'strict': None}
Enter fullscreen mode Exit fullscreen mode

Function.from_openai already replaced None with defaults for parameters and description, but not for strict. On the Mistral side, strict is a boolean that defaults to False, so Pydantic rejected None.

This is a silent integration bug: each library is right on its own, and the failure only shows up where they meet.

The fix

Two lines in Function.from_openai: when strict is None, drop the field so that the model falls back to its default (False).

if filtered.get("strict") is None:
    filtered.pop("strict", None)
Enter fullscreen mode Exit fullscreen mode

True and False behave as before. Two tests cover Function.from_openai and Tool.from_openai with "strict": None. The full suite (1,294 tests), ruff and mypy all pass.

Timeline:

  • issue #393 on October 20 (minimal reproduction);
  • PR #396 the same day;
  • merged on October 21.

If you are on 1.12.0 today

Until the next release, dump your tools without null fields:

Function.from_openai(tool.model_dump(exclude_none=True))
Enter fullscreen mode Exit fullscreen mode

If your tools arrive as raw JSON (in a gateway, for example), drop strict when it is null before converting.

A second report, fixed differently by Mistral

The same day I reported an inconsistency in the tokenizers (issue #395). Tekkenizer.decode still accepted the legacy integer special token policies (0, 1, 2), but id_to_byte_piece rejected them.

I had proposed aligning id_to_byte_piece with decode. The maintainers confirmed the bug and chose the opposite approach: they removed the integer backward compatibility everywhere (PR #402, October 21). It is their design call, and a consistent one.

What it means for you: if your code calls decode(..., special_token_policy=1), it will fail with the next release. Switch to the enum, or to its string value, now:

from mistral_common.tokens.tokenizers.base import SpecialTokenPolicy
tokenizer.decode(tokens, special_token_policy=SpecialTokenPolicy.KEEP)  # or "keep"
Enter fullscreen mode Exit fullscreen mode

Key takeaways

  • A tool dumped by the OpenAI SDK contains "strict": None. mistral-common 1.12.0 rejects it, and the next release accepts it.
  • Workaround today: model_dump(exclude_none=True).
  • Integer special token policies (0, 1, 2) are going away: use SpecialTokenPolicy.
  • When migrating from OpenAI to Mistral, test the conversion of your tools exactly as your code produces them, not only hand-written dicts.

Related

This is the second contribution merged by Mistral AI, after PR #349 on offline tokenizers (article). Other fixes are awaiting review: Three silent bugs in Mistral AI's Python libraries.


Zakaria Khchiche, freelance Data & AI Tech Lead: 200+ AI agents in production (Copilot Studio, Azure AI Foundry, Azure OpenAI), contributor to Microsoft Agent Framework and Mistral AI. LinkedIn ยท Website

Want your team to build agents like these? I run a hands-on Copilot Studio training (in French, with Spar-x, Qualiopi-certified, eligible for OPCO funding in France): https://zakariakhchiche.github.io/formation-copilot-studio/ and a free AI Act article 4 kit: https://zakariakhchiche.github.io/kit-ai-act/

Top comments (0)