openclaw - ✅(Solved) Fix [Bug]: resolveFallbackRetryPrompt discards original user prompt on model fallback retry [4 pull requests, 1 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
openclaw/openclaw#65760Fetched 2026-04-14 05:40:28
View on GitHub
Comments
0
Participants
1
Timeline
11
Reactions
0
Participants
Timeline (top)
referenced ×5cross-referenced ×4labeled ×2

When a model call fails and OpenClaw triggers a fallback retry, resolveFallbackRetryPrompt() replaces the entire original user prompt with the fixed string "Continue where you left off. The previous model attempt failed or timed out.". This discards the original task instruction, causing the agent to operate on incomplete context and potentially produce incorrect or unintended results.

Root Cause

When a model call fails and OpenClaw triggers a fallback retry, resolveFallbackRetryPrompt() replaces the entire original user prompt with the fixed string "Continue where you left off. The previous model attempt failed or timed out.". This discards the original task instruction, causing the agent to operate on incomplete context and potentially produce incorrect or unintended results.

Fix Action

Fixed

PR fix notes

PR #65778: fix(agent): preserve original prompt in fallback retry instead of replacing it

Description (problem / solution / changelog)

Summary

When a model call fails and OpenClaw triggers a fallback retry, resolveFallbackRetryPrompt() was replacing the entire original user prompt with the fixed string "Continue where you left off. The previous model attempt failed or timed out.". This caused the agent to lose the original task context and potentially produce incorrect or unintended results.

This change prepends the retry notice to the original prompt so the agent retains full context of what it was asked to do.

Change Type

  • Bug fix

Related Issue

Fixes #65760

Testing

  • pnpm test src/agents/command/attempt-execution.test.ts — 17/17 passed
  • pnpm tsgo — passed
  • pnpm lint — 0 warnings, 0 errors

Changed files

  • src/agents/command/attempt-execution.helpers.ts (modified, +1/-1)
  • src/agents/command/attempt-execution.test.ts (modified, +3/-1)

PR #65805: fix(fallback): preserve original prompt in resolveFallbackRetryPrompt

Description (problem / solution / changelog)

Summary

When a model call fails and triggers a fallback retry on a session with existing history, resolveFallbackRetryPrompt() replaces the original user prompt with the generic string "Continue where you left off. The previous model attempt failed or timed out.". This causes the fallback model to lose the original task instruction entirely, forcing it to infer the task from session history alone — which can produce incorrect or unintended results.

Root Cause

// Before: original body is discarded
if (params.sessionHasHistory) {
  return "Continue where you left off. The previous model attempt failed or timed out.";
}

When isFallbackRetry=true and sessionHasHistory=true, the function returned only the generic retry message, discarding params.body.

Fix

Prepend the retry notice to the original body instead of replacing it:

const retryNotice =
  "[System: The previous model attempt failed or timed out. Continue where you left off.]";
return \`\${retryNotice}\\n\\n\${params.body}\`;

The fallback model now receives both:

  1. Context that a retry occurred (so it can leverage session history)
  2. The full original task instruction (so it knows what to do)

Test Changes

Updated the existing test to verify:

  • The original body is preserved in the output
  • The retry notice appears as a prefix
  • The original body follows after the notice

All 17 existing tests pass.

Impact

  • All users with model fallback/retry configured benefit
  • Agents no longer silently lose their task when a model times out
  • Subagent spawns are most affected since their task instruction is their only context

Fixes #65760

Changed files

  • src/agents/command/attempt-execution.helpers.ts (modified, +6/-1)
  • src/agents/command/attempt-execution.test.ts (modified, +12/-8)

PR #65885: fix: preserve original prompt in resolveFallbackRetryPrompt

Description (problem / solution / changelog)

Summary

Fixes #65760

Changes

  • Fix resolveFallbackRetryPrompt() to preserve the original user prompt instead of discarding it on model fallback retry
  • Prepend a retry notice [Retry after previous model attempt failed or timed out.] to the original prompt body
  • Update corresponding test expectations

Details

Previously, when a model call failed and triggered a fallback retry, resolveFallbackRetryPrompt() replaced the entire original prompt with the generic message "Continue where you left off. The previous model attempt failed or timed out.". This caused the agent to lose all task context.

Now the function prepends a retry notice to the original prompt, preserving full task context while informing the model that a retry occurred.

Before

return "Continue where you left off. The previous model attempt failed or timed out.";

After

return `[Retry after previous model attempt failed or timed out.]\n\n${params.body}`;

Test plan

  • Existing unit test updated to verify new behavior
  • All pre-commit checks pass (lint, type-check, import cycle checks)
  • Verify that fallback retry preserves original prompt in a live session

Changed files

  • src/agents/command/attempt-execution.helpers.ts (modified, +1/-1)
  • src/agents/command/attempt-execution.test.ts (modified, +2/-2)

PR #66029: fix(agents): preserve original prompt on model fallback retry (#65760)

Description (problem / solution / changelog)

Summary

When a model call fails and OpenClaw triggers a fallback retry, `resolveFallbackRetryPrompt()` replaced the entire original user body with the fixed string `"Continue where you left off. The previous model attempt failed or timed out."` This discarded the original task instruction entirely, forcing the fallback model to reconstruct the task from session history alone — sometimes impossible (e.g. freshly spawned subagent where only the last message survives), sometimes just wrong.

Prepend the retry context to the original body instead so the fallback model has both the recovery signal AND the task:

``` [Retry after the previous model attempt failed or timed out]

<original body> \`\`\`

The existing subagent-spawn branch (no persisted session history) is unaffected — that path still returns `params.body` verbatim.

Credit to #65760 for a clean root-cause trace (incl. pointer to `attempt-execution.helpers.ts:resolveFallbackRetryPrompt`).

Closes #65760.

Changes

  • `src/agents/command/attempt-execution.helpers.ts` — prepend retry prefix to `params.body` instead of replacing it
  • `src/agents/command/attempt-execution.test.ts` — update the matching test to assert the new prefixed form; leave other tests (first attempt, no-history subagent) untouched

Test plan

  • Updated test exercises the fallback-with-history path directly
  • No-history subagent test still asserts `originalBody` return
  • First-attempt test still asserts `originalBody` return
  • Minimal diff, no surrounding refactor

🤖 Generated with Claude Code

Changed files

  • src/agents/command/attempt-execution.helpers.ts (modified, +7/-1)
  • src/agents/command/attempt-execution.test.ts (modified, +2/-2)

Code Example

Source code in `dist/agent-command-8TL7BESJ.js` (v2026.4.9) and `dist/agent-command-BUw17dbz.js` (v2026.4.11):


function resolveFallbackRetryPrompt(params) {
	if (!params.isFallbackRetry) return params.body;
	if (!params.sessionHasHistory) return params.body;
	return "Continue where you left off. The previous model attempt failed or timed out.";
}


Called in `runAgentAttempt()`:

const effectivePrompt = resolveFallbackRetryPrompt({
    body: params.body,
    isFallbackRetry: params.isFallbackRetry,
    sessionHasHistory: params.sessionHasHistory
});


Session log evidence (session ec19b29b):
- Line 25: `customType: "model-snapshot"`, provider: xiaomi, model: mimo-v2-pro
- Line 26: `role: "user"`, content: `"Continue where you left off. The previous model attempt failed or timed out."` (no sender metadata)
- Line 27: `role: "assistant"`, model: mimo-v2-pro (fallback retry response)

---

function resolveFallbackRetryPrompt(params) {
    if (!params.isFallbackRetry) return params.body;
    if (!params.sessionHasHistory) return params.body;
    return "[System: Previous model attempt failed. Continuing from where you left off.]\n\n" + params.body;
}
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When a model call fails and OpenClaw triggers a fallback retry, resolveFallbackRetryPrompt() replaces the entire original user prompt with the fixed string "Continue where you left off. The previous model attempt failed or timed out.". This discards the original task instruction, causing the agent to operate on incomplete context and potentially produce incorrect or unintended results.

Steps to reproduce

  1. Configure an agent with a model that may timeout or fail (e.g., xiaomi/mimo-v2-pro).
  2. Spawn a subagent with a specific task instruction (e.g., [Subagent Task]: RECORD時系列整列).
  3. The first model call fails or times out.
  4. OpenClaw triggers fallback retry, calling resolveFallbackRetryPrompt().
  5. The function replaces the original prompt with "Continue where you left off. The previous model attempt failed or timed out.".
  6. The agent receives only this generic message with no reference to the original task.
  7. Session log shows the message injected as role: "user" with no sender metadata, making it indistinguishable from a real user message.

Expected behavior

The original user prompt should be preserved and passed to the fallback model, possibly with a prefix like "[Retry after previous attempt failed] Original task: <original prompt>". The agent should continue with full context of what it was asked to do, not start from a generic message.

Actual behavior

The agent receives only "Continue where you left off. The previous model attempt failed or timed out." instead of the original task. In the observed case, a subagent spawned with task [Subagent Task]: RECORD時系列整列 received only the generic retry message after the first model call (xiaomi/mimo-v2-pro) timed out. The agent had to infer the task from session history alone, risking incorrect or unintended actions. Session log confirms the message was injected as role: "user" with no sender metadata.

OpenClaw version

2026.4.9

Operating system

Ubuntu 22.04.5 LTS

Install method

npm global

Model

xiaomi/mimo-v2-pro (primary, timed out) → xiaomi/mimo-v2-pro (fallback retry)

Provider / routing chain

openclaw -> xiaomi (direct API)

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Source code in `dist/agent-command-8TL7BESJ.js` (v2026.4.9) and `dist/agent-command-BUw17dbz.js` (v2026.4.11):


function resolveFallbackRetryPrompt(params) {
	if (!params.isFallbackRetry) return params.body;
	if (!params.sessionHasHistory) return params.body;
	return "Continue where you left off. The previous model attempt failed or timed out.";
}


Called in `runAgentAttempt()`:

const effectivePrompt = resolveFallbackRetryPrompt({
    body: params.body,
    isFallbackRetry: params.isFallbackRetry,
    sessionHasHistory: params.sessionHasHistory
});


Session log evidence (session ec19b29b):
- Line 25: `customType: "model-snapshot"`, provider: xiaomi, model: mimo-v2-pro
- Line 26: `role: "user"`, content: `"Continue where you left off. The previous model attempt failed or timed out."` (no sender metadata)
- Line 27: `role: "assistant"`, model: mimo-v2-pro (fallback retry response)

Impact and severity

Affected: All users who use model fallback/retry (any provider that can timeout or fail) Severity: High (agent loses original task context, can produce unintended results) Frequency: Intermittent (whenever a model call fails and triggers fallback retry) Consequence: Agent operates without original instructions, may perform incorrect actions, waste tokens, or produce harmful outputs. The retry message appears as a regular user message in session logs, making it hard to distinguish from real user input.

Additional information

The same code exists in the latest version (2026.4.11). The fix should modify resolveFallbackRetryPrompt() to prepend the retry notice to the original prompt instead of replacing it, e.g.:

function resolveFallbackRetryPrompt(params) {
    if (!params.isFallbackRetry) return params.body;
    if (!params.sessionHasHistory) return params.body;
    return "[System: Previous model attempt failed. Continuing from where you left off.]\n\n" + params.body;
}

This preserves the original task instruction while informing the model that a retry occurred.

extent analysis

TL;DR

Modify the resolveFallbackRetryPrompt() function to prepend a retry notice to the original prompt instead of replacing it.

Guidance

  • Identify the resolveFallbackRetryPrompt() function in the codebase and update its logic to preserve the original prompt.
  • Prepend a retry notice to the original prompt, as shown in the provided example code.
  • Verify that the updated function correctly handles fallback retries and preserves the original task instruction.
  • Test the modified function with different scenarios, including model timeouts and failures, to ensure it produces the expected output.

Example

function resolveFallbackRetryPrompt(params) {
    if (!params.isFallbackRetry) return params.body;
    if (!params.sessionHasHistory) return params.body;
    return "[System: Previous model attempt failed. Continuing from where you left off.]\n\n" + params.body;
}

Notes

The provided code snippet suggests that the issue is specific to the resolveFallbackRetryPrompt() function, and modifying it should resolve the problem. However, it's essential to thoroughly test the updated function to ensure it works as expected in all scenarios.

Recommendation

Apply the workaround by modifying the resolveFallbackRetryPrompt() function to prepend the retry notice to the original prompt. This approach preserves the original task instruction while informing the model that a retry occurred, addressing the high-severity issue.

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

The original user prompt should be preserved and passed to the fallback model, possibly with a prefix like "[Retry after previous attempt failed] Original task: <original prompt>". The agent should continue with full context of what it was asked to do, not start from a generic message.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING