hermes - ✅(Solved) Fix [Bug]: cron path still emits HTTP 400 reasoning_content error on deepseek-v4-flash after #15213 closure [1 pull requests, 4 comments, 3 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#15741Fetched 2026-04-26 05:25:25
View on GitHub
Comments
4
Participants
3
Timeline
11
Reactions
1
Author
Timeline (top)
commented ×4labeled ×4closed ×1cross-referenced ×1

Error Message

ERROR [cron_<job_id>20260424_133042] 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'}} ERROR [cron<job_id>20260424_142831] 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'}} ERROR [cron<job_id>_20260425_133011] 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'}}

Root Cause

A recurring cron job continues to fail with the DeepSeek reasoning_content 400 error after the closure of #15213 (which had been filed for the same root cause in the cron path). Three consecutive runs across 2026-04-24 and 2026-04-25 produced the same Non-retryable client error on Hermes v0.11.0.

Fix Action

Workaround

Switching the job to model: gpt-5.3-codex / provider: openai-codex (or any non-thinking provider) restores normal operation.

PR fix notes

PR #15792: fix(deepseek): pad reasoning_content on plain assistant turns in thinking mode (#15741)

Description (problem / solution / changelog)

Summary

  • Extend the DeepSeek thinking-mode reasoning_content echo to cover plain assistant messages (no tool_calls), not just tool-call turns
  • Kimi's narrower scope (tool-call turns only) is preserved
  • 2 test changes: one renamed+corrected assertion, one new Kimi contrast test

The bug

After 93a2d6b3 landed (fixing tool-call turns in #15250), interactive sessions with mixed plain + tool-call turns continued to fail with HTTP 400:

The reasoning_content in the thinking mode must be passed back to the API.

DeepSeek V4 thinking mode requires reasoning_content on every assistant message in history. A plain assistant turn (e.g. "Sure, let me check that for you.") that is stored without the field poisons all subsequent replays of that session.

The fix

_build_assistant_message — Remove the tool_calls guard from the DeepSeek empty-string fallback. When the API response carries reasoning_content=None (attribute present, value None), plain messages now also get reasoning_content="" pinned at creation time.

_copy_reasoning_content_for_api — Split the Kimi and DeepSeek paths:

  • Kimi: still only pads tool-call turns (existing behavior, no regression)
  • DeepSeek: now pads all assistant turns — injects reasoning_content="" whenever no real reasoning was stored

Test plan

  • Before (stash fix, keep test changes): test_deepseek_plain_assistant_also_paddedFAILED (AssertionError: 'reasoning_content' not in {})
  • After (restore fix): 22 passed in test_deepseek_reasoning_content_echo.py
  • Adjacent transport tests unchanged: 41 passed in tests/agent/transports/test_chat_completions.py
  • test_kimi_plain_assistant_not_padded confirms Kimi scope is unchanged

Related

  • Fixes #15741
  • Follow-up to #15250 / #15353 (93a2d6b3)

🤖 Generated with Claude Code

Changed files

  • run_agent.py (modified, +13/-13)
  • tests/run_agent/test_deepseek_reasoning_content_echo.py (modified, +23/-12)

Code Example

ERROR [cron_<job_id>_20260424_133042] 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'}}
ERROR [cron_<job_id>_20260424_142831] 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'}}
ERROR [cron_<job_id>_20260425_133011] 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'}}

---

## Response

(No response generated)

---

{
  "schedule": {"kind": "cron", "expr": "<any cron expression>"},
  "model": "deepseek-v4-flash",
  "provider": "deepseek-v4",
  "deliver": "origin",
  "enabled": true,
  "prompt": "<any prompt that requires one tool call before the final response>"
}

---

Read the README at https://github.com/<any-public-repo> and return three bullet points summarizing it. After reading, respond with the bullets.
RAW_BUFFERClick to expand / collapse

Bug Description

A recurring cron job continues to fail with the DeepSeek reasoning_content 400 error after the closure of #15213 (which had been filed for the same root cause in the cron path). Three consecutive runs across 2026-04-24 and 2026-04-25 produced the same Non-retryable client error on Hermes v0.11.0.

This issue is filed as a follow-up to:

  • #15213 (closed 2026-04-25 08:56 UTC) — same root cause in the cron path
  • #15717 (open, P2) — general bug for the same provider/model combination
  • #15700 (open) — related: missing thinking: disabled parameter

The closure of #15213 may have addressed the main-loop case but did not cover the cron auxiliary path, since failures continued to occur after that closure.

Steps to Reproduce

  1. Hermes Agent v0.11.0 (2026.4.23), Python 3.11.14, OpenAI SDK 2.32.0.
  2. Create a recurring cron job whose model field is set to deepseek-v4-flash and provider to deepseek-v4. The prompt must require at least one tool call before producing the final response (any multi-step prompt that reads from a tool and then summarizes works).
  3. Let the cron fire on its scheduled trigger.
  4. Inspect ~/.hermes/logs/agent.log (or errors.log) and the cron output file under ~/.hermes/cron/output/<job_id>/<date>.md.

Expected Behavior

The agent completes the multi-turn tool-call workflow and the final response is delivered via deliver: origin.

Actual Behavior

The agent makes one or more tool calls successfully, then on a follow-up turn the API request returns HTTP 400. Reproduced verbatim from errors.log (job ID and timestamps anonymized only with respect to the run number — error string is unmodified):

ERROR [cron_<job_id>_20260424_133042] 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'}}
ERROR [cron_<job_id>_20260424_142831] 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'}}
ERROR [cron_<job_id>_20260425_133011] 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'}}

The cron output file then contains:

## Response

(No response generated)

…and the job is marked last_status: error with the synthesized message Agent completed but produced empty response (model error, timeout, or misconfiguration). No retry. No delivery.

Why this is not covered by #15213

#15213 reports _copy_reasoning_content_for_api works in the main loop but breaks in the cron auxiliary path "after several auxiliary calls (title_generation, vision_analyze, auxiliary auto-detect)". The case here has the same surface symptom but a simpler trigger:

  • The failing turn is the immediate continuation after a tool result, not after auxiliary metadata calls.
  • No auxiliary title_generation or vision_analyze involvement (text-only prompt, plain tool call, no images, no title generation).
  • Failure reproduces deterministically on every run since 2026-04-24, including after #15213 was closed.

This suggests the reasoning_content passthrough is missing in the cron path's primary tool-result → next-turn handoff, not just the auxiliary calls listed in #15213.

Minimal reproduction

A minimal cron job definition that triggers the bug (extracted from ~/.hermes/cron/jobs.json):

{
  "schedule": {"kind": "cron", "expr": "<any cron expression>"},
  "model": "deepseek-v4-flash",
  "provider": "deepseek-v4",
  "deliver": "origin",
  "enabled": true,
  "prompt": "<any prompt that requires one tool call before the final response>"
}

A minimal repro prompt:

Read the README at https://github.com/<any-public-repo> and return three bullet points summarizing it. After reading, respond with the bullets.

The model performs the read, then the next request to the DeepSeek API returns 400.

Workaround

Switching the job to model: gpt-5.3-codex / provider: openai-codex (or any non-thinking provider) restores normal operation.

Environment

  • Hermes Agent v0.11.0 (2026.4.23)
  • Python 3.11.14
  • OpenAI SDK 2.32.0
  • macOS Darwin 25.3.0
  • Models confirmed affected on deepseek-v4 provider:
    • deepseek-v4-flash
    • deepseek-v4-pro (per #15213; also reproduced via interactive /model switch on the same Hermes instance)

Suggested fix

Audit every code path that builds the next API request from prior turns — not just run_agent.py::_copy_reasoning_content_for_api — and ensure reasoning_content from the previous assistant message is preserved when the message is sent back to a thinking-mode model. The cron path appears to be one such missing site; auxiliary calls (per #15213) are another.

Defense-in-depth option: when the provider is deepseek-v4 and the next request targets a model name matching *-flash/*-pro/*-thinking, validate that the last assistant turn carries reasoning_content before sending; if not, refuse the request locally with a clearer error than the upstream HTTP 400.

extent analysis

TL;DR

The cron job fails due to a missing reasoning_content passthrough in the cron path's primary tool-result → next-turn handoff, causing a 400 error from the DeepSeek API.

Guidance

  • Review the code that builds the next API request from prior turns to ensure reasoning_content is preserved when sending the message back to a thinking-mode model.
  • Check the cron path specifically, as it appears to be a missing site for this preservation.
  • Consider adding a defense-in-depth validation to check for reasoning_content in the last assistant turn before sending the request when the provider is deepseek-v4 and the model name matches *-flash/*-pro/*-thinking.
  • Verify the fix by running the cron job with the modified code and checking for successful completion without 400 errors.

Example

No code snippet is provided as the issue does not include specific code that needs to be modified. However, the suggested fix involves auditing and modifying the code that builds the next API request to preserve reasoning_content.

Notes

The issue is specific to the deepseek-v4 provider and models deepseek-v4-flash and deepseek-v4-pro. The suggested fix should be applied to the Hermes Agent code to ensure compatibility with these models.

Recommendation

Apply the suggested fix by auditing and modifying the code to preserve reasoning_content in the cron path and adding a defense-in-depth validation. This should resolve the 400 error issue with the DeepSeek API.

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]: cron path still emits HTTP 400 reasoning_content error on deepseek-v4-flash after #15213 closure [1 pull requests, 4 comments, 3 participants]