Mistral API 422 errors from invalid message fields

NousResearch/hermes-agent · cluster 134

Data as of

Nothing open on GitHub. Fix merged in #253. Check it covers your case.

The short answer

0open issues
0open PRs
5items grouped
Known?
Yes. 5 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #253. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #253. That is separate from the fix event.
Still open
Nothing open on GitHub.

A cluster of issues and fixes addressing HTTP 422 errors when calling the Mistral API, caused by internal or unsupported fields (such as finish_reason and reasoning params) being included in API message payloads. The fixes involve stripping or skipping these fields before making API calls.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #253 fix(agent): strip finish_reason from assistant messages to fix Mistral 422 errors

    merged to main

    files: run_agent.py

    Show the diff
    • run_agent.py
      @@ -2087,7 +2087,8 @@ def _build_api_kwargs(self, api_messages: list) -> dict:
               _is_openrouter = "openrouter" in self.base_url.lower()
               _is_nous = "nousresearch" in self.base_url.lower()
       
      -        if _is_openrouter or _is_nous:
      +        _is_mistral = "api.mistral.ai" in self.base_url.lower()
      +        if (_is_openrouter or _is_nous) and not _is_mistral:
                   if self.reasoning_config is not None:
                       extra_body["reasoning"] = self.reasoning_config
                   else:
      @@ -2232,6 +2233,7 @@ def flush_memories(self, messages: list = None, min_turns: int = None):
                           if reasoning:
                               api_msg["reasoning_content"] = reasoning
                       api_msg.pop("reasoning", None)
      +                api_msg.pop("finish_reason", None)
                       api_messages.append(api_msg)
       
                   if self._cached_system_prompt:
      @@ -2859,6 +2861,9 @@ def run_conversation(
                       # We've copied it to 'reasoning_content' for the API above
                       if "reasoning" in api_msg:
                           api_msg.pop("reasoning")
      +                # Remove finish_reason - not accepted by strict APIs (e.g. Mistral)
      +                if "finish_reason" in api_msg:
      +                    api_msg.pop("finish_reason")
                       # Keep 'reasoning_details' - OpenRouter uses this for multi-turn reasoning context
                       # The signature field helps maintain reasoning continuity
                       api_messages.append(api_msg)

3 PRs closed without merging

From the close comments: closed without comment 1 · superseded by another PR 1 · other 1

  • #138 fix: sanitize internal fields from API messages · superseded by another PR
  • #250 fix(agent): strip finish_reason and internal fields before API calls · other → #253
  • #252 fix(agent): skip reasoning param for Mistral API to prevent 422 errors · closed without comment
Closed issues · 1
  • Closed#134Error code: 422 when calling mistral api
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.40: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Merged PRs
#253
Closed issues
1
Attempts
3 PRs closed without merging
Fix link checked
2 Mar 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.

For your agent

The same facts, typed.