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:
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
- Hermes Agent v0.11.0 (2026.4.23), Python 3.11.14, OpenAI SDK 2.32.0.
- 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).
- Let the cron fire on its scheduled trigger.
- 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:
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:
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.
Bug Description
A recurring cron job continues to fail with the DeepSeek
reasoning_content400 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 sameNon-retryable client erroron Hermes v0.11.0.This issue is filed as a follow-up to:
thinking: disabledparameterThe 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
modelfield is set todeepseek-v4-flashandprovidertodeepseek-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).~/.hermes/logs/agent.log(orerrors.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):The cron output file then contains:
## Response (No response generated)…and the job is marked
last_status: errorwith the synthesized messageAgent 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_apiworks 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:title_generationorvision_analyzeinvolvement (text-only prompt, plain tool call, no images, no title generation).This suggests the
reasoning_contentpassthrough 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:
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
deepseek-v4provider:deepseek-v4-flashdeepseek-v4-pro(per [Bug]: HTTP 400 "reasoning_content must be passed back" with deepseek-v4-pro in cron/auxiliary path (thinking mode works in main loop, breaks elsewhere) #15213; also reproduced via interactive/modelswitch 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 ensurereasoning_contentfrom 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-v4and the next request targets a model name matching*-flash/*-pro/*-thinking, validate that the last assistant turn carriesreasoning_contentbefore sending; if not, refuse the request locally with a clearer error than the upstream HTTP 400.