[Bug]: DeepSeek PR review fails after three reasoning-only responses
Summary
The Codex PR Review workflow is routed to the DeepSeek review script for the current provider configuration. On PR #428, the configured deepseek-v4-flash model returned an empty final message.content on all three attempts, while returning substantial reasoning_content. The script failed before posting any GitHub review.
This is a review-model/output integration failure, not a code-review rejection or a failed product test. The deeper cause (provider behavior, thinking configuration, or output-budget exhaustion) is not yet proven by the retained logs.
Evidence
- Affected PR: #428
- Reviewed head:
abf810e9e7f7bcfd3e1e1d915c817e81e144101d - Failed workflow: https://github.com/OpenCoworkAI/open-codesign/actions/runs/35456727130
- Failed job / step: pr-review / Run DeepSeek for PR Review
- Time: 2026-09-19, approximately 17:00:52–17:02:36 UTC
- Configured model:
deepseek-v4-flash; effort:high - Response model field:
deepseek-flash
Sanitized failure shape:
DeepSeek output invalid on attempt 1/3: DeepSeek API returned no message content
DeepSeek output invalid on attempt 2/3: DeepSeek API returned no message content
Error: DeepSeek API returned no message content
Process completed with exit code 1The response previews show message.content: "" with non-empty reasoning_content. The workflow did not run the Codex action fallback and did not submit any review. Request credentials/endpoints are intentionally omitted here.
Current implementation and suspected contributors
- Review entrypoint does not override the output budget.
- Shared request helper defaults to
max_tokens: 8192, requests JSON output, and only explicitly enables thinking fordeepseek-reasoner/deepseek-v4-pro*. Fordeepseek-v4-flashit omits the thinking setting; the observed response nevertheless contains reasoning. - Retry handling adds a JSON-format reminder but keeps the same budget/model/thinking policy.
- Empty-content diagnostics truncate the raw response before the useful trailing
finish_reason/ usage fields, so the logs do not establish whether the output budget was exhausted.
A large review input (27 changed files, 3938 additions in this case) plus reasoning consuming the output budget is a plausible hypothesis, not a confirmed root cause.
Expected behavior
A valid, non-empty JSON review body is posted, or the workflow clearly reports that automated review was unavailable. Model/provider failures must not be presented as code findings, and reasoning text must not be substituted for a completed review or approval.
Suggested follow-up / acceptance criteria
- Log safe structured metadata on empty output: requested/returned model, finish reason, usage, and content/reasoning lengths; do not dump credentials, prompts, or raw reasoning.
- Verify the provider's current thinking/output-budget semantics for
deepseek-v4-flashand configure them explicitly where supported. - Add a bounded, cost-aware recovery policy for reasoning-only or length-exhausted output instead of repeating the same ineffective request three times (appropriate output budget, smaller review chunks, or an explicitly configured fallback).
- Add mocked API regression tests for reasoning-only output,
finish_reason=length, valid final JSON, malformed JSON, and exhausted retries; assert no blank/fabricated review is posted. - Reproduce with a similarly sized PR and verify successful review submission or an actionable infrastructure-failure summary.
Merge disposition
Per the maintainer's explicit request, #428 was squash-merged after verifying that CI (lint/typecheck/tests/build), CodeQL, and Dependency Review all passed, with no submitted blocking review. The only failing check was this automated review execution. The merge used an exact head-SHA guard and did not use an admin override or change repository protections.
Merge commit: c25a5765c6ce7eec6c7e184643613bfcd3bfa403.
Source: OpenCoworkAI/open-codesign