openclaw - 💡(How to fix) Fix [Bug]: Hardcoded GPT-5 reply brevity caps silently truncate replies, no config opt-out

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…

On openclaw 2026.5.12 with openai/gpt-5.3-codex, applyOpenAIGptChatReplyGuard in dist/agent-runner.runtime-Dv_D_ax0.js silently shortens assistant replies and appends a literal "...", with no config knob exposed to disable it.

Root Cause

  1. Run openclaw 2026.5.12 with an agent whose model resolves to openai/gpt-5.3-codex via the Codex runtime (provider="openai-codex").
  2. Send the agent a short prompt (≤120 chars, no "?", not containing any of detail/depth/explain/compare/why/how) that elicits a numbered multi-item list reply.
  3. Observe the reply: cut at the 6th boundary of the regex /(?<=[.!?])\s+/u — which for a numbered list lands between items 2 and 3 because "1. " and "2. " each match — with a literal "..." appended.

Fix Action

Fix / Workaround

Workaround currently applied locally — short-circuit the function via the dist:

This is wiped by every pnpm/npm reinstall of openclaw, and the dist filename hash changes per release. Requesting a config knob (e.g. chatGuard.enabled: false, or per-agent override) so the workaround isn't necessary.

Code Example

Code excerpts (openclaw 2026.5.12, dist/agent-runner.runtime-Dv_D_ax0.js):

function shouldApplyOpenAIGptChatGuard(params) {
  if (params.provider !== "openai" && params.provider !== "openai-codex") return false;
  return /^gpt-5(?:[.-]|$)/i.test(params.model ?? "");
}

const GPT_CHAT_BREVITY_ACK_MAX_CHARS = 420;
const GPT_CHAT_BREVITY_ACK_MAX_SENTENCES = 3;
const GPT_CHAT_BREVITY_SOFT_MAX_CHARS = 900;
const GPT_CHAT_BREVITY_SOFT_MAX_SENTENCES = 6;

function applyOpenAIGptChatReplyGuard(params) {
  if (params.isHeartbeat || !shouldApplyOpenAIGptChatGuard({provider, model}) || !params.payloads?.length) return;
  const trimmedCommand = params.commandBody.trim();
  const isAckTurn = isLikelyExecutionAckPrompt(trimmedCommand);
  const allowSoftCap = !isAckTurn && trimmedCommand.length > 0 && trimmedCommand.length <= 120 &&
    !/\b(?:detail|detailed|depth|deep dive|explain|compare|walk me through|why|how)\b/i.test(trimmedCommand);
  for (const payload of params.payloads) {
    const text = normalizeOptionalString(payload.text);
    if (!text || payload.isError || payload.isReasoning || payload.mediaUrl ||
        (payload.mediaUrls?.length ?? 0) > 0 || payload.interactive ||
        text.includes("")) continue;
    if (isAckTurn) {
      payload.text = shortenChattyFinalReplyText(text, {
        maxChars: GPT_CHAT_BREVITY_ACK_MAX_CHARS, maxSentences: GPT_CHAT_BREVITY_ACK_MAX_SENTENCES
      });
      continue;
    }
    if (allowSoftCap && scoreChattyFinalReplyText(text) >= 4)
      payload.text = shortenChattyFinalReplyText(text, {
        maxChars: GPT_CHAT_BREVITY_SOFT_MAX_CHARS, maxSentences: GPT_CHAT_BREVITY_SOFT_MAX_SENTENCES
      });
  }
}

No chatGuard / brevityGuard / gptChatGuard / chatReplyGuard / disableBrevity config key exists anywhere in dist/ (verified by grep -roE). The guard emits no log line when it fires.
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

On openclaw 2026.5.12 with openai/gpt-5.3-codex, applyOpenAIGptChatReplyGuard in dist/agent-runner.runtime-Dv_D_ax0.js silently shortens assistant replies and appends a literal "...", with no config knob exposed to disable it.

Steps to reproduce

  1. Run openclaw 2026.5.12 with an agent whose model resolves to openai/gpt-5.3-codex via the Codex runtime (provider="openai-codex").
  2. Send the agent a short prompt (≤120 chars, no "?", not containing any of detail/depth/explain/compare/why/how) that elicits a numbered multi-item list reply.
  3. Observe the reply: cut at the 6th boundary of the regex /(?<=[.!?])\s+/u — which for a numbered list lands between items 2 and 3 because "1. " and "2. " each match — with a literal "..." appended.

Expected behavior

NOT_ENOUGH_INFO

Actual behavior

Reply received in Discord ends with literal "...". A 3-item numbered list reply was cut at "3...". The trailing "..." is appended by shortenChattyFinalReplyText at dist/agent-runner.runtime-Dv_D_ax0.js:

return shortened.replace(/[.,;:!?-]*$/u, "").trimEnd() + "...";

The guard is invoked post-model in the success branch that runs after runResult.payloads is populated, so it post-processes already-generated content.

OpenClaw version

v2026.5.12

Operating system

linux 6.8.0-111-generic x64 · node 22.22.2

Install method

npm global (/usr/lib/node_modules/openclaw/)

Model

openai/gpt-5.3-codex

Provider / routing chain

Discord channel -> openclaw 2026.5.12 gateway -> Codex runtime (openai-codex provider) -> gpt-5.3-codex

Additional provider/model setup details

Single agent in ~/.openclaw/openclaw.json with agentRuntime.id="codex" on the renamed entries (per the 2026.5.12 openai-codex/* namespace migration). model-fallback/decision log lines name candidate openai/gpt-5.3-codex. openclaw status "Runtime" column shows "OpenAI Codex" for the Discord direct session.

<img width="774" height="233" alt="Image" src="https://github.com/user-attachments/assets/827cf449-30db-4133-b266-d63cd2197abf" />

Logs, screenshots, and evidence

Code excerpts (openclaw 2026.5.12, dist/agent-runner.runtime-Dv_D_ax0.js):

function shouldApplyOpenAIGptChatGuard(params) {
  if (params.provider !== "openai" && params.provider !== "openai-codex") return false;
  return /^gpt-5(?:[.-]|$)/i.test(params.model ?? "");
}

const GPT_CHAT_BREVITY_ACK_MAX_CHARS = 420;
const GPT_CHAT_BREVITY_ACK_MAX_SENTENCES = 3;
const GPT_CHAT_BREVITY_SOFT_MAX_CHARS = 900;
const GPT_CHAT_BREVITY_SOFT_MAX_SENTENCES = 6;

function applyOpenAIGptChatReplyGuard(params) {
  if (params.isHeartbeat || !shouldApplyOpenAIGptChatGuard({provider, model}) || !params.payloads?.length) return;
  const trimmedCommand = params.commandBody.trim();
  const isAckTurn = isLikelyExecutionAckPrompt(trimmedCommand);
  const allowSoftCap = !isAckTurn && trimmedCommand.length > 0 && trimmedCommand.length <= 120 &&
    !/\b(?:detail|detailed|depth|deep dive|explain|compare|walk me through|why|how)\b/i.test(trimmedCommand);
  for (const payload of params.payloads) {
    const text = normalizeOptionalString(payload.text);
    if (!text || payload.isError || payload.isReasoning || payload.mediaUrl ||
        (payload.mediaUrls?.length ?? 0) > 0 || payload.interactive ||
        text.includes("")) continue;
    if (isAckTurn) {
      payload.text = shortenChattyFinalReplyText(text, {
        maxChars: GPT_CHAT_BREVITY_ACK_MAX_CHARS, maxSentences: GPT_CHAT_BREVITY_ACK_MAX_SENTENCES
      });
      continue;
    }
    if (allowSoftCap && scoreChattyFinalReplyText(text) >= 4)
      payload.text = shortenChattyFinalReplyText(text, {
        maxChars: GPT_CHAT_BREVITY_SOFT_MAX_CHARS, maxSentences: GPT_CHAT_BREVITY_SOFT_MAX_SENTENCES
      });
  }
}

No chatGuard / brevityGuard / gptChatGuard / chatReplyGuard / disableBrevity config key exists anywhere in dist/ (verified by grep -roE). The guard emits no log line when it fires.

Impact and severity

  • Affected users/systems/channels: openclaw setups using openai/gpt-5* models via the openai or openai-codex providers, on any channel (verified on Discord)
  • Severity: medium — silently corrupts user-facing replies; does not crash, lose state, or affect non-GPT-5 models
  • Frequency: deterministic for any reply where the guard's preconditions are met (ACK turn or soft-cap path)
  • Consequence: user-facing reply is incomplete with a literal "..." appended, indistinguishable to a casual reader from the model itself trailing off; no log line is emitted

Additional information

Workaround currently applied locally — short-circuit the function via the dist:

sudo sed -i 's|function applyOpenAIGptChatReplyGuard(params) {|function applyOpenAIGptChatReplyGuard(params) { return;|'
/usr/lib/node_modules/openclaw/dist/agent-runner.runtime-Dv_D_ax0.js openclaw gateway restart

This is wiped by every pnpm/npm reinstall of openclaw, and the dist filename hash changes per release. Requesting a config knob (e.g. chatGuard.enabled: false, or per-agent override) so the workaround isn't necessary.

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…

FAQ

Expected behavior

NOT_ENOUGH_INFO

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: Hardcoded GPT-5 reply brevity caps silently truncate replies, no config opt-out