hermes - ✅(Solved) Fix [Bug]: DeepSeek reasoning models crash with HTTP 400 on multi-turn sessions — reasoning_content dropped during session reload [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#17825Fetched 2026-05-01 05:55:39
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
0
Timeline (top)
labeled ×6cross-referenced ×2commented ×1

Error Message

Environment

Repository:  https://github.com/NousResearch/hermes-agent.git
Upstream HEAD: 627abbb1e (chore(release): map davidvv in AUTHOR_MAP)
Local changes: gateway/run.py (2-line fix), run_agent.py (gap-filler)
Provider:      DeepSeek (custom, base_url: https://api.deepseek.com/v1)
Model:         deepseek-v4-pro


Error Output

From ~/.hermes/logs/errors.log — multiple sessions, same crash pattern:


2026-04-25 10:23:30,754 ERROR [20260425_064607_5cbb93af] root:
  Non-retryable client error: Error code: 400 -
  {'error': {'message': 'The reasoning_content in the thinking mode
   must be passed back to the API.', 'type': 'invalid_request_error',
   'param': None, 'code': 'invalid_request_error'}}

2026-04-25 10:27:22,828 ERROR [20260425_064607_5cbb93af] root:
  (same session, retry — same 400)

2026-04-25 10:30:09,120 ERROR [20260425_102739_d592f4f1] root:
  (new session, second turn — same 400)

2026-04-27 08:05:38,043 WARNING [20260427_080149_e689a3] root:
  Failed to get summary response: Error code: 400 -
  'The reasoning_content in the thinking mode must be passed back to the API.'

2026-04-28 15:08:09,337 WARNING [20260428_142857_d1ae44] root:
  Failed to get summary response: Error code: 400 -
  'The reasoning_content in the thinking mode must be passed back to the API.'


Error hits both the main agent loop AND the session summarizer — because both go through _run_agent → agent_history rebuild.

The Broken Pipeline (Step by Step)


TURN 1:
  DeepSeek API → returns reasoning_content: "Let me think..."
  run_agent.py → stores in msg["reasoning_content"]
  session.py    → saves to SQLite ✅ (line 1151 — reasoning_content IS in schema)
  session.py    → writes to JSONL transcript ✅

TURN 2:
  session.py    → reads history from SQLite ✅ (line 1183 — reasoning_content IS loaded)
  run.py:9940   → rebuilds agent_history from loaded messages
                  ❌ DROPS reasoning_content — not in the preserved-fields tuple
  agent_history → [{role:"user",...}, {role:"assistant", content:"...", reasoning:...}]
                  ^ reasoning_content is ABSENT
  run_agent.py  → _copy_reasoning_content_for_api() gap-filler fires
                  BUT: it copies from msg["reasoning_content"] (which is missing)
                  → nothing to copy, gap remains
  DeepSeek API  → sees: prior assistant turn WITHOUT reasoning_content
                  current turn WITH reasoning_content
                  → HTTP 400: "reasoning_content must be passed back"

ALL SUBSEQUENT TURNS: same 400 — session is permanently broken


What Each File Does (and Doesn't Do)

| File | Saves reasoning_content? | Loads reasoning_content? | Rebuilds history with it? |
|---|---|---|---|
| gateway/session.py | ✅ line 1151 | ✅ line 1183 | N/A |
| gateway/run.py | ❌ line 9940 | N/A | ❌ dropped |
| run_agent.py | ✅ stores in msg dict | ✅ gap-filler at 7259 | ✅ but operates on already-broken agent_history |

The problem is in gateway/run.py alone. Session I/O is fine. The gap-filler in run_agent.py is correct but helpless — it receives history that was already stripped during the DB→agent_history rebuild.

The Fix (Unified Diff)

diff
--- a/gateway/run.py
+++ b/gateway/run.py
@@ -9937,10 +9937,11 @@
                         if role == "assistant":
-                            for _rkey in ("reasoning", "reasoning_details",
+                            for _rkey in ("reasoning", "reasoning_content",
+                                          "reasoning_details",
                                           "codex_reasoning_items"):
                                 _rval = msg.get(_rkey)
-                                if _rval:
+                                if _rval is not None:
                                     entry[_rkey] = _rval


Change 1: Add "reasoning_content" — this is DeepSeek's native reasoning field, stored correctly by session.py but dropped during history rebuild.

Change 2: if _rval: → if _rval is not None: — the gap-filler in run_agent.py sets reasoning_content to "" on tool-call turns that lack it. if _rval evaluates "" as falsy and drops it again, causing the same 400 on the next turn. is not None preserves empty strings through the DB round-trip.

Reproducibility

100% reproducible. Any multi-turn DeepSeek session on unpatched main will crash on turn 2. The first message always succeeds (no prior history to violate), then the session is dead. Affects all DeepSeek reasoning models (V4-Pro, R1, Reasoner) via both /v1 and /anthropic endpoints.

Root Cause

The session is dead at this point — every subsequent message in that session produces the same 400 because prior assistant turns are missing reasoning_content and DeepSeek refuses to process a history where some assistant messages have it and others don't.

Fix Action

Fix / Workaround

100% reproducible. Any multi-turn DeepSeek session on unpatched main will crash on turn 2. The first message always succeeds (no prior history to violate), then the session is dead. Affects all DeepSeek reasoning models (V4-Pro, R1, Reasoner) via both /v1 and /anthropic endpoints.

PR fix notes

PR #5976: fix(gateway): preserve reasoning-only assistant turns on reload

Description (problem / solution / changelog)

Summary

Gateway reload currently drops assistant turns that have empty visible content but do carry replay-relevant reasoning state (reasoning, reasoning_details, codex_reasoning_items). That means Hermes persists those fields, but a fresh gateway turn silently discards them before the next API call.

This patch keeps those assistant turns in replay history while still dropping truly empty assistant shells.

Motivation

Hermes already preserves reasoning continuity state for multi-turn providers. Gateway sessions create a fresh AIAgent per message, so transcript replay is the continuity boundary for every follow-up turn. If the reload path filters out reasoning-only assistant turns, users can lose continuity exactly in the scenarios where these fields matter most:

  • reasoning-capable OpenRouter / Anthropic-compatible providers
  • Codex reasoning-only interim turns
  • longer gateway conversations where follow-up quality depends on replay fidelity

This tackles one narrow instance of the broader live-loop vs. session-reload drift tracked in #4555.

What Changed

  • preserve assistant messages during gateway history filtering when they carry:
    • reasoning
    • reasoning_details
    • codex_reasoning_items
  • replay those turns with content: "" when there is no visible assistant text
  • keep existing behavior for:
    • session_meta and system filtering
    • tool-call and tool-result replay
    • dropping truly empty assistant shells
    • history_offset-based transcript slicing

Why This Scope

I intentionally kept this gateway-only and avoided a broader replay refactor. The goal here is to fix one real continuity bug with the smallest safe diff and the clearest review surface.

Testing

  • venv/bin/python -m pytest -o addopts='' tests/gateway/test_transcript_offset.py
  • venv/bin/python -m pytest -o addopts='' tests/gateway/test_session.py
  • venv/bin/python -m pytest -o addopts='' tests/test_anthropic_adapter.py
  • venv/bin/python -m pytest -o addopts='' tests/test_provider_parity.py

Refs #4555

Changed files

  • gateway/run.py (modified, +13/-4)
  • tests/gateway/test_transcript_offset.py (modified, +129/-2)

PR #17991: fix(agent): preserve all thinking blocks for DeepSeek /anthropic endpoint

Description (problem / solution / changelog)

Summary

  • Preserve ALL thinking blocks for DeepSeek /anthropic and Kimi /coding endpoints, not just unsigned ones. Only redacted_thinking data payloads (Anthropic-proprietary) are still stripped.
  • Add error classifier pattern for DeepSeek's specific 400 error ("thinking must be passed back"), which lacks the "signature" keyword required by the existing thinking_signature check.
  • Update tests to reflect the new behavior: blocks with provider-specific signatures are preserved.

Why

DeepSeek v4's /anthropic endpoint may sign its own thinking blocks. The existing _preserve_unsigned_thinking branch strips any block with a truthy signature or data field, assuming all signatures are Anthropic-proprietary. When DeepSeek's own signed blocks are stripped, the next replay fails with:

HTTP 400: The content[].thinking in the thinking mode must be passed back to the API.

PR #17223 adds DeepSeek to the _preserve_unsigned_thinking path but keeps the "strip signed" logic, which may still fail if DeepSeek signs its own blocks. This PR takes the next step: trust the upstream provider's own blocks and only strip blocks that are recognizably foreign (redacted_thinking data payloads).

Changes

FileChange
agent/anthropic_adapter.pyRemove b.get("signature") check; only strip redacted_thinking data payloads
agent/error_classifier.pyAdd DeepSeek-specific error pattern as retryable thinking_signature
tests/agent/test_deepseek_anthropic_thinking.pyUpdate test: signed blocks now expected to be preserved

Test plan

  • pytest tests/agent/test_deepseek_anthropic_thinking.py -v — 9 passed
  • pytest tests/run_agent/test_deepseek_reasoning_content_echo.py -v — 23 passed
  • pytest tests/agent/test_error_classifier.py -v -k thinking — 3 passed
  • Manual verification: DeepSeek v4-pro multi-turn tool calls on /anthropic endpoint no longer fails

Related

  • Fixes: #16748
  • Related: #17223, #17400, #16844, #17825
  • Alternative to: #17223 (this PR goes further by preserving signed blocks)

🤖 Generated with Claude Code

Changed files

  • agent/anthropic_adapter.py (modified, +12/-8)
  • agent/error_classifier.py (modified, +16/-0)
  • tests/agent/test_deepseek_anthropic_thinking.py (modified, +16/-9)

Code Example

Environment


    Repository:  https://github.com/NousResearch/hermes-agent.git
    Upstream HEAD: 627abbb1e (chore(release): map davidvv in AUTHOR_MAP)
    Local changes: gateway/run.py (2-line fix), run_agent.py (gap-filler)
    Provider:      DeepSeek (custom, base_url: https://api.deepseek.com/v1)
    Model:         deepseek-v4-pro


    Error Output

    From ~/.hermes/logs/errors.log — multiple sessions, same crash pattern:


    2026-04-25 10:23:30,754 ERROR [20260425_064607_5cbb93af] root:
      Non-retryable client error: Error code: 400 -
      {'error': {'message': 'The reasoning_content in the thinking mode
       must be passed back to the API.', 'type': 'invalid_request_error',
       'param': None, 'code': 'invalid_request_error'}}

    2026-04-25 10:27:22,828 ERROR [20260425_064607_5cbb93af] root:
      (same session, retry — same 400)

    2026-04-25 10:30:09,120 ERROR [20260425_102739_d592f4f1] root:
      (new session, second turn — same 400)

    2026-04-27 08:05:38,043 WARNING [20260427_080149_e689a3] root:
      Failed to get summary response: Error code: 400 -
      'The reasoning_content in the thinking mode must be passed back to the API.'

    2026-04-28 15:08:09,337 WARNING [20260428_142857_d1ae44] root:
      Failed to get summary response: Error code: 400 -
      'The reasoning_content in the thinking mode must be passed back to the API.'


    Error hits both the main agent loop AND the session summarizer — because both go through _run_agent → agent_history rebuild.

    The Broken Pipeline (Step by Step)


    TURN 1:
      DeepSeek API → returns reasoning_content: "Let me think..."
      run_agent.py → stores in msg["reasoning_content"]
      session.py    → saves to SQLite  (line 1151 — reasoning_content IS in schema)
      session.py    → writes to JSONL transcript ✅

    TURN 2:
      session.py    → reads history from SQLite  (line 1183 — reasoning_content IS loaded)
      run.py:9940   → rebuilds agent_history from loaded messages
DROPS reasoning_content — not in the preserved-fields tuple
      agent_history → [{role:"user",...}, {role:"assistant", content:"...", reasoning:...}]
                      ^ reasoning_content is ABSENT
      run_agent.py_copy_reasoning_content_for_api() gap-filler fires
                      BUT: it copies from msg["reasoning_content"] (which is missing)
                      → nothing to copy, gap remains
      DeepSeek API  → sees: prior assistant turn WITHOUT reasoning_content
                      current turn WITH reasoning_content
HTTP 400: "reasoning_content must be passed back"

    ALL SUBSEQUENT TURNS: same 400 — session is permanently broken


    What Each File Does (and Doesn't Do)

    | File | Saves reasoning_content? | Loads reasoning_content? | Rebuilds history with it? |
    |---|---|---|---|
    | gateway/session.py | ✅ line 1151 | ✅ line 1183 | N/A |
    | gateway/run.py | ❌ line 9940 | N/A | ❌ dropped |
    | run_agent.py | ✅ stores in msg dict | ✅ gap-filler at 7259 | ✅ but operates on already-broken agent_history |

    The problem is in gateway/run.py alone. Session I/O is fine. The gap-filler in run_agent.py is correct but helpless — it receives history that was already stripped during the DB→agent_history rebuild.

    The Fix (Unified Diff)

    diff
    --- a/gateway/run.py
    +++ b/gateway/run.py
    @@ -9937,10 +9937,11 @@
                             if role == "assistant":
    -                            for _rkey in ("reasoning", "reasoning_details",
    +                            for _rkey in ("reasoning", "reasoning_content",
    +                                          "reasoning_details",
                                               "codex_reasoning_items"):
                                     _rval = msg.get(_rkey)
    -                                if _rval:
    +                                if _rval is not None:
                                         entry[_rkey] = _rval


    Change 1: Add "reasoning_content"this is DeepSeek's native reasoning field, stored correctly by session.py but dropped during history rebuild.

    Change 2: if _rval:if _rval is not None: — the gap-filler in run_agent.py sets reasoning_content to "" on tool-call turns that lack it. if _rval evaluates "" as falsy and drops it again, causing the same 400 on the next turn. is not None preserves empty strings through the DB round-trip.

    Reproducibility

    100% reproducible. Any multi-turn DeepSeek session on unpatched main will crash on turn 2. The first message always succeeds (no prior history to violate), then the session is dead. Affects all DeepSeek reasoning models (V4-Pro, R1, Reasoner) via both /v1 and /anthropic endpoints.

---
RAW_BUFFERClick to expand / collapse

Bug Description

When using DeepSeek reasoning models (V4-Pro, R1, Reasoner) as the primary model, multi-turn conversations crash with HTTP 400 on the second turn and beyond:

Non-retryable client error: Error code: 400 - {'error': {'message':
'The reasoning_content in the thinking mode must be passed back to the API.'}}

Steps to Reproduce

  1. Configure DeepSeek V4 Pro as the primary model with base_url: https://api.deepseek.com/v1 (the correct endpoint — /anthropic has its own separate issue) 2. Start a conversation — turn 1 succeeds ✅ 3. Send a second message in the same session — HTTP 400 ❌

Expected Behavior

This causes a chain failure:

1. Turn 1: DeepSeek returns reasoning_content → saved to DB ✅
2. Turn 2: session reloaded from DB → reasoning_content stripped ❌
3. Turn 2 runs: new response has reasoning_content, but prior assistant messages don't → HTTP 400

The _copy_reasoning_content_for_api() gap-fix in run_agent.py can't help here — it operates on api_messages, not the base history that gets built from DB reload.

Actual Behavior

On the first message in a session, everything works normally — DeepSeek responds with reasoning and a final answer. On the second message (same session), the agent crashes with a non-retryable HTTP 400:

Non-retryable client error: Error code: 400 - {'error': {'message':
'The reasoning_content in the thinking mode must be passed back to the API.',
'type': 'invalid_request_error', 'param': None, 'code': 'invalid_request_error'}}


The crash happens inside the gateway's agent loop. From ~/.hermes/logs/errors.log:


ERROR    gateway.run:_run_agent:9847 — Non-retryable client error (HTTP 400):
{'error': {'message': 'The reasoning_content in the thinking mode must be
passed back to the API.', 'type': 'invalid_request_error', 'param': None,
'code': 'invalid_request_error'}}


The session is dead at this point — every subsequent message in that session produces the same 400 because prior assistant turns are missing reasoning_content and DeepSeek refuses to process a history where some assistant messages have it and others don't.

Affected Component

CLI (interactive chat)

Messaging Platform (if gateway-related)

No response

Debug Report

Environment


    Repository:  https://github.com/NousResearch/hermes-agent.git
    Upstream HEAD: 627abbb1e (chore(release): map davidvv in AUTHOR_MAP)
    Local changes: gateway/run.py (2-line fix), run_agent.py (gap-filler)
    Provider:      DeepSeek (custom, base_url: https://api.deepseek.com/v1)
    Model:         deepseek-v4-pro


    Error Output

    From ~/.hermes/logs/errors.log — multiple sessions, same crash pattern:


    2026-04-25 10:23:30,754 ERROR [20260425_064607_5cbb93af] root:
      Non-retryable client error: Error code: 400 -
      {'error': {'message': 'The reasoning_content in the thinking mode
       must be passed back to the API.', 'type': 'invalid_request_error',
       'param': None, 'code': 'invalid_request_error'}}

    2026-04-25 10:27:22,828 ERROR [20260425_064607_5cbb93af] root:
      (same session, retry — same 400)

    2026-04-25 10:30:09,120 ERROR [20260425_102739_d592f4f1] root:
      (new session, second turn — same 400)

    2026-04-27 08:05:38,043 WARNING [20260427_080149_e689a3] root:
      Failed to get summary response: Error code: 400 -
      'The reasoning_content in the thinking mode must be passed back to the API.'

    2026-04-28 15:08:09,337 WARNING [20260428_142857_d1ae44] root:
      Failed to get summary response: Error code: 400 -
      'The reasoning_content in the thinking mode must be passed back to the API.'


    Error hits both the main agent loop AND the session summarizer — because both go through _run_agent → agent_history rebuild.

    The Broken Pipeline (Step by Step)


    TURN 1:
      DeepSeek API → returns reasoning_content: "Let me think..."
      run_agent.py → stores in msg["reasoning_content"]
      session.py    → saves to SQLite ✅ (line 1151 — reasoning_content IS in schema)
      session.py    → writes to JSONL transcript ✅

    TURN 2:
      session.py    → reads history from SQLite ✅ (line 1183 — reasoning_content IS loaded)
      run.py:9940   → rebuilds agent_history from loaded messages
                      ❌ DROPS reasoning_content — not in the preserved-fields tuple
      agent_history → [{role:"user",...}, {role:"assistant", content:"...", reasoning:...}]
                      ^ reasoning_content is ABSENT
      run_agent.py  → _copy_reasoning_content_for_api() gap-filler fires
                      BUT: it copies from msg["reasoning_content"] (which is missing)
                      → nothing to copy, gap remains
      DeepSeek API  → sees: prior assistant turn WITHOUT reasoning_content
                      current turn WITH reasoning_content
                      → HTTP 400: "reasoning_content must be passed back"

    ALL SUBSEQUENT TURNS: same 400 — session is permanently broken


    What Each File Does (and Doesn't Do)

    | File | Saves reasoning_content? | Loads reasoning_content? | Rebuilds history with it? |
    |---|---|---|---|
    | gateway/session.py | ✅ line 1151 | ✅ line 1183 | N/A |
    | gateway/run.py | ❌ line 9940 | N/A | ❌ dropped |
    | run_agent.py | ✅ stores in msg dict | ✅ gap-filler at 7259 | ✅ but operates on already-broken agent_history |

    The problem is in gateway/run.py alone. Session I/O is fine. The gap-filler in run_agent.py is correct but helpless — it receives history that was already stripped during the DB→agent_history rebuild.

    The Fix (Unified Diff)

    diff
    --- a/gateway/run.py
    +++ b/gateway/run.py
    @@ -9937,10 +9937,11 @@
                             if role == "assistant":
    -                            for _rkey in ("reasoning", "reasoning_details",
    +                            for _rkey in ("reasoning", "reasoning_content",
    +                                          "reasoning_details",
                                               "codex_reasoning_items"):
                                     _rval = msg.get(_rkey)
    -                                if _rval:
    +                                if _rval is not None:
                                         entry[_rkey] = _rval


    Change 1: Add "reasoning_content" — this is DeepSeek's native reasoning field, stored correctly by session.py but dropped during history rebuild.

    Change 2: if _rval: → if _rval is not None: — the gap-filler in run_agent.py sets reasoning_content to "" on tool-call turns that lack it. if _rval evaluates "" as falsy and drops it again, causing the same 400 on the next turn. is not None preserves empty strings through the DB round-trip.

    Reproducibility

    100% reproducible. Any multi-turn DeepSeek session on unpatched main will crash on turn 2. The first message always succeeds (no prior history to violate), then the session is dead. Affects all DeepSeek reasoning models (V4-Pro, R1, Reasoner) via both /v1 and /anthropic endpoints.

Operating System

Ubuntu 24.04

Python Version

3.11

Hermes Version

No response

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

In gateway/run.py (~line 9939), when the gateway reloads session history from the database (_run_agent, building agent_history), it preserves reasoning fields on assistant messages — but reasoning_content is missing from the list:

python
Current upstream code (BROKEN):
if role == "assistant":
    for _rkey in ("reasoning",              # ← preserved
                  "reasoning_details",       # ← preserved
                  "codex_reasoning_items"):  # ← preserved
        _rval = msg.get(_rkey)
        if _rval:                            # ← falsy guard skips ""
            entry[_rkey] = _rval
reasoning_content is SILENTLY DROPPED


This causes a chain failure:

1. Turn 1: DeepSeek returns reasoning_content → saved to DB ✅
2. Turn 2: session reloaded from DB → reasoning_content stripped ❌
3. Turn 2 runs: new response has reasoning_content, but prior assistant messages don't → HTTP 400

The _copy_reasoning_content_for_api() gap-fix in run_agent.py can't help here — it operates on api_messages, not the base history that gets built from DB reload.

Proposed Fix (optional)

Two changes in gateway/run.py:

python
FIXED:
if role == "assistant":
    for _rkey in ("reasoning", "reasoning_content",   # ← ADDED
                  "reasoning_details",
                  "codex_reasoning_items"):
        _rval = msg.get(_rkey)
        if _rval is not None:                         # ← was: if _rval:
            entry[_rkey] = _rval


1. Add "reasoning_content" to the preserved fields tuple — this is DeepSeek's native reasoning field
2. Change if _rval: to if _rval is not None: — the gap-filler in run_agent.py sets reasoning_content to "" (empty string) on turns that lack it, and if _rval evaluates "" as falsy, dropping it again

Why is not None matters

DeepSeek requires reasoning_content to be present on every assistant message when the model is in thinking mode — even on tool-call turns where the field is empty string. The gap-fixer in run_agent.py fills missing ones with "", but without the is not None guard, empty strings are lost in the DB round-trip, causing the same 400.

Tested

Verified live against api.deepseek.com/v1:

| Scenario | Result |
|---|---|
| reasoning_content present on all turns | OK |
| reasoning_content missing on prior turns | HTTP 400 |
| Tool calls + reasoning_content | OK |
| Tool calls without reasoning_content | HTTP 400 |

Related

There's also a gap-filler in run_agent.py (_copy_reasoning_content_for_api()) that fills missing reasoning_content with "" on outgoing API messages. That fix is necessary but insufficient — it can't compensate for the DB reload stripping the field entirely from history.

Environment

- Hermes Agent version: up to current main
- Provider: DeepSeek (any reasoning model: V4-Pro, R1, Reasoner)
- Config: base_url: https://api.deepseek.com/v1, provider: custom

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

The issue can be fixed by modifying the gateway/run.py file to preserve the reasoning_content field when rebuilding the agent_history from the database.

Guidance

  • The root cause of the issue is the missing reasoning_content field in the preserved fields tuple in gateway/run.py, which causes the field to be dropped during the DB reload.
  • To fix this, add "reasoning_content" to the preserved fields tuple and change the if _rval: guard to if _rval is not None: to preserve empty strings.
  • The modified code should look like this:
if role == "assistant":
    for _rkey in ("reasoning", "reasoning_content", "reasoning_details", "codex_reasoning_items"):
        _rval = msg.get(_rkey)
        if _rval is not None:
            entry[_rkey] = _rval
  • This change will ensure that the reasoning_content field is preserved during the DB reload and the agent_history rebuild.

Example

No additional code snippet is needed, as the modified code is provided above.

Notes

  • This fix is specific to the gateway/run.py file and does not affect other parts of the codebase.
  • The is not None guard is necessary to preserve empty strings, which are set by the gap-filler in run_agent.py.

Recommendation

Apply the workaround by modifying the gateway/run.py file as described above. This fix is necessary to preserve the reasoning_content field and prevent the HTTP 400 error.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug]: DeepSeek reasoning models crash with HTTP 400 on multi-turn sessions — reasoning_content dropped during session reload [2 pull requests, 1 comments, 2 participants]