openclaw - ✅(Solved) Fix TypeError: Cannot read properties of undefined (reading "replace") during embedded agent run (v2026.4.1) [1 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#60113Fetched 2026-04-08 02:36:05
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
cross-referenced ×2referenced ×1

Error Message

TypeError: Cannot read properties of undefined (reading 'replace')

Fix Action

Fixed

PR fix notes

PR #60157: fix(agents): add null guards to prevent TypeError on undefined .replace() calls

Description (problem / solution / changelog)

Problem

Embedded agent runs intermittently crash with:

TypeError: Cannot read properties of undefined (reading 'replace')

This occurs in two distinct trigger patterns:

  1. Model failover timeout chain: When all fallback models timeout sequentially, the error fires during error message construction in the failover handler, where formatAssistantErrorText() or extractAssistantText() receives an undefined/malformed assistant message.

  2. Normal run with tool errors: During runs where tools return errors (e.g., read tool called without path), text extraction and sanitization functions call .replace() on values that may be undefined.

Each crash also writes an empty assistant message to the transcript, which can accumulate and cause downstream API errors.

Root Cause

Multiple functions across the codebase accept string parameters but are called with potentially undefined values. The .replace() method is then invoked on undefined, causing a TypeError. The main offenders:

  1. extractTextFromChatContent() — default normalizeText callback: text.replace(/\s+/g, " ") with no null guard
  2. normalizeAnthropicBaseUrl()baseUrl.replace() with no null guard
  3. extractAssistantText() / formatAssistantErrorText() — operate on potentially undefined assistant message objects
  4. sanitizeText callbacks — chained .replace() calls without guarding input
  5. Several strip* functions that return the input when falsy (preserving undefined) instead of returning ""

Fix

Add defensive null guards across all identified code paths:

FileFunctionChange
shared/chat-content.tsextractTextFromChatContentGuard default normalizeText: (text ?? "").replace(...)
agents/pi-embedded-utils.tsextractAssistantTextEarly return "" if msg is undefined; guard sanitizeText and normalizeText callbacks
agents/pi-embedded-helpers/errors.tsformatAssistantErrorTextEarly return undefined if msg is undefined
agents/pi-embedded-helpers/messaging-dedupe.tsnormalizeTextForComparisonEarly return "" if text is falsy
plugins/provider-model-compat.tsnormalizeAnthropicBaseUrl(baseUrl ?? "").replace(...)
agents/tool-mutation.tsbuildToolActionFingerprintTernary guard on meta before .trim().replace()
agents/internal-runtime-context.tsstripInternalRuntimeContextReturn "" instead of undefined/""/null
agents/tools/sessions-helpers.tssanitizeTextContentReturn "" instead of falsy input
shared/text/reasoning-tags.tsstripReasoningTagsFromTextReturn "" instead of falsy input

All guards are defensive and do not change behavior for valid (non-undefined) inputs.

Testing

These changes are safe null-coalescing guards. Each modified function:

  • Returns the same output for all valid string inputs
  • Returns "" (instead of crashing) for undefined/null inputs
  • Does not change the function signature or public API

Fixes #60113

Changed files

  • src/agents/internal-runtime-context.ts (modified, +1/-1)
  • src/agents/pi-embedded-helpers/errors.ts (modified, +4/-1)
  • src/agents/pi-embedded-helpers/messaging-dedupe.ts (modified, +3/-0)
  • src/agents/pi-embedded-utils.ts (modified, +18/-9)
  • src/agents/tool-mutation.ts (modified, +1/-1)
  • src/agents/tools/sessions-helpers.ts (modified, +1/-1)
  • src/plugins/provider-model-compat.ts (modified, +1/-1)
  • src/shared/chat-content.ts (modified, +1/-1)
  • src/shared/text/reasoning-tags.ts (modified, +1/-1)

Code Example

TypeError: Cannot read properties of undefined (reading 'replace')

---

05:34:19 [diagnostic] lane task error: lane=session:agent:clawdoctor:main durationMs=209209 error="FailoverError: LLM request timed out."
05:34:19 [model-fallback/decision] decision=candidate_failed ... next=amazon-bedrock/global.anthropic.claude-sonnet-4-6
05:34:35 [agent/embedded] embedded run agent end: isError=true error=Cannot read properties of undefined (reading 'replace')

---

13:50:41 [agent/embedded] read tool called without path: toolCallId=tooluse_yVKLYPEEQQveLdOnWBj1NW
13:51:35 [agent/embedded] embedded run agent end: isError=true error=Cannot read properties of undefined (reading 'replace')
RAW_BUFFERClick to expand / collapse

Bug Description

Embedded agent runs intermittently crash with:

TypeError: Cannot read properties of undefined (reading 'replace')

Logged as embedded run agent end: isError=true with no full stack trace (only error.message is captured).

This occurs in two distinct trigger patterns:

Pattern 1: Model failover timeout chain

When all fallback models timeout sequentially (e.g., opus-4-6 → sonnet-4-6 → opus-4-5 → haiku), the error fires during error message construction in the failover handler.

05:34:19 [diagnostic] lane task error: lane=session:agent:clawdoctor:main durationMs=209209 error="FailoverError: LLM request timed out."
05:34:19 [model-fallback/decision] decision=candidate_failed ... next=amazon-bedrock/global.anthropic.claude-sonnet-4-6
05:34:35 [agent/embedded] embedded run agent end: isError=true error=Cannot read properties of undefined (reading 'replace')

Pattern 2: Normal run with tool errors

The error also occurs during normal (non-failover) runs, often preceded by tool call issues like read tool called without path:

13:50:41 [agent/embedded] read tool called without path: toolCallId=tooluse_yVKLYPEEQQveLdOnWBj1NW
13:51:35 [agent/embedded] embedded run agent end: isError=true error=Cannot read properties of undefined (reading 'replace')

Side Effect

Each crash writes an empty assistant message (content: "") to the session transcript/database. When using lossless-claw (LCM plugin), these accumulate and eventually trigger Anthropic API errors (messages.0 is empty).

Dist Analysis

The error is logged at pi-embedded-bukGSgEe.js:37337:13 (the throw new FailoverError(message, ...) line), called from queue-ClGptXsO.js:110:22 (lane task executor).

Since the dist is minified and no source maps are available at runtime, the exact .replace() call site could not be determined. Candidate locations identified:

  1. extractTextFromChatContent() in minimax-vlm-Qh0ipRyy.js:18normalizeText default uses text.replace(/\s+/g, " ") which crashes if the sanitize chain returns undefined
  2. client.baseUrl.replace() in embedding-provider-BbCMyWBL.js:85 and memory-core-host-engine-embeddings-CURmoLEe.js — no null guard on client.baseUrl
  3. buildEmbeddedRunPayloads() in pi-embedded-bukGSgEe.js:36351 — calls formatAssistantErrorText() and extractAssistantText$1() on potentially malformed assistant objects

Note: Issue #21923 reported the same error in v2026.2.19 with client.baseUrl.replace() as the likely cause. That specific case may have been fixed, but the error persists in v2026.4.1 through different code paths.

Steps to Reproduce

  1. Configure model fallback chain with Bedrock models (opus-4-6, sonnet-4-6, opus-4-5, haiku-4-5)
  2. Have a session with large context (~1M+ tokens) that causes timeouts
  3. Send a message — all models timeout → .replace() crash during error handling
  4. OR: Have an agent call a tool with missing parameters → .replace() crash during error response construction

Expected Behavior

Failover/error handling should gracefully construct error messages with null-safe property access.

Actual Behavior

Crash with TypeError: Cannot read properties of undefined (reading 'replace'), empty assistant message written to transcript.

Environment

  • OpenClaw: v2026.4.1 (npm/pnpm)
  • Node: v22.22.0
  • OS: Linux 6.8.0-101-generic (x64)
  • Provider: amazon-bedrock (Anthropic models)
  • Models: opus-4-6, sonnet-4-6, opus-4-5, haiku-4-5

Request

Could the error logging be enhanced to capture error.stack (not just error.message) in embedded run agent end? This would make it much easier to pinpoint the exact .replace() call site in the minified dist.

extent analysis

TL;DR

The most likely fix involves adding null checks for properties before calling replace() on them, particularly in extractTextFromChatContent(), client.baseUrl.replace(), and buildEmbeddedRunPayloads().

Guidance

  • Review the code in minimax-vlm-Qh0ipRyy.js, embedding-provider-BbCMyWBL.js, memory-core-host-engine-embeddings-CURmoLEe.js, and pi-embedded-bukGSgEe.js to identify where replace() is called without proper null checks.
  • Add null guards for text in extractTextFromChatContent() and for client.baseUrl in embedding-provider-BbCMyWBL.js and memory-core-host-engine-embeddings-CURmoLEe.js.
  • Consider enhancing error logging to capture error.stack in addition to error.message for better debugging.

Example

// Before
function extractTextFromChatContent(text) {
  return text.replace(/\s+/g, " ");
}

// After
function extractTextFromChatContent(text) {
  return text && text.replace(/\s+/g, " ");
}

Notes

The issue seems to be related to missing null checks in several places, but without the exact source code or stack traces, it's difficult to pinpoint the exact cause. Enhancing error logging to include error.stack would greatly help in identifying the root cause.

Recommendation

Apply workaround by adding null checks for properties before calling replace() on them, as this is a more immediate and feasible solution given the current information.

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