Skip to content

🐛 fix: guard non-string content in context-engine to prevent e.trim errors#13753

Merged
arvinxx merged 1 commit into
canaryfrom
fix/context-engine-non-string-content-guard
Apr 12, 2026
Merged

🐛 fix: guard non-string content in context-engine to prevent e.trim errors#13753
arvinxx merged 1 commit into
canaryfrom
fix/context-engine-non-string-content-guard

Conversation

@arvinxx

@arvinxx arvinxx commented Apr 12, 2026

Copy link
Copy Markdown
Member

💻 Change Type

  • 🐛 fix
  • ✅ test

🔗 Related Issue

Follow-up to #13715 (add typeof guard before .trim() calls in context engine) — that PR covered BaseProcessor.isEmptyMessage, BaseSystemRoleProvider, and SystemRoleInjector, but two other unguarded paths in the context engine still throw e.trim is not a function for chats whose history contains non-string content (multimodal parts array, null tool turns).

🔀 Description of Change

Two unguarded .trim() / string-concatenation paths in the context-engine still reproduce e.trim is not a function (seen in production traces):

  1. resolveTopicReferences.ts — the fallback lookupMessages branch calls m.content?.trim() and m.content!.trim(). Historical messages can carry non-string content (multimodal parts array, null from tool-only assistant turns). When that happens, the TypeError is swallowed by the outer try/catch at the per-topic level and the entire recent-messages fallback silently drops. Guard with typeof m.content === 'string' before trimming.

  2. MessageContent.ts processorlet textContent = message.content || '' followed by (textContent + '\n\n' + filesContext).trim(). When message.content is already a parts array (an upstream processor normalized it earlier), + coerces via Array.prototype.toString() and emits [object Object],[object Object]\n\n<!-- SYSTEM CONTEXT ... straight into the LLM prompt. Normalize to a text string first — use the string directly, or extract type === 'text' parts from the array.

🧪 How to Test

  • Tested locally
  • Added/updated tests

Regression tests added:

  • resolveTopicReferences.test.ts
    • should skip messages whose content is not a string (array / object) — mixed-content fallback keeps string messages, skips array/object ones.
    • should not throw when every fallback message has non-string content — graceful fallthrough to no-context.
  • MessageContent.test.ts
    • should not stringify array content when concatenating file context — multimodal user message + file context must not produce [object Object] in the text part.

Full @lobechat/context-engine suite: 757/757 pass.

cd packages/context-engine
bunx vitest run --silent='passed-only'

📝 Additional Information

Both files predate #13715 — the trim fix only patched three known spots. These two are pre-existing latent bugs that the production trace surfaced after non-string content started flowing through both paths.

…is not a function`

Two unguarded `.trim()` / string-concatenation paths in the context-engine
could throw or produce garbage text when a message's `content` is not a
plain string (multimodal parts array, null tool turns). Both are reached
in normal chat and trigger `e.trim is not a function` in production.

- `resolveTopicReferences`: filter out non-string content in the fallback
  `lookupMessages` path before calling `.trim()`. Without this guard, the
  outer try/catch swallows the TypeError and drops the whole fallback.
- `MessageContent` processor: normalize `message.content` (string or
  parts array) before concatenating file context, instead of relying on
  implicit `toString()` coercion which emitted `[object Object]` into
  the LLM prompt.

Adds regression tests for both paths.
@vercel

vercel Bot commented Apr 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lobehub Ready Ready Preview, Comment Apr 12, 2026 11:20am

Request Review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@codecov

codecov Bot commented Apr 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.56%. Comparing base (37bf1bd) to head (2896da8).
⚠️ Report is 3 commits behind head on canary.

Additional details and impacted files
@@            Coverage Diff            @@
##           canary   #13753     +/-   ##
=========================================
  Coverage   66.56%   66.56%             
=========================================
  Files        2022     2022             
  Lines      171262   171265      +3     
  Branches    20683    17425   -3258     
=========================================
+ Hits       113998   114000      +2     
- Misses      57139    57140      +1     
  Partials      125      125             
Flag Coverage Δ
app 58.61% <ø> (-0.01%) ⬇️
database 92.49% <ø> (ø)
packages/agent-runtime 79.72% <ø> (ø)
packages/context-engine 83.37% <100.00%> (+0.04%) ⬆️
packages/conversation-flow 92.36% <ø> (ø)
packages/file-loaders 87.02% <ø> (ø)
packages/memory-user-memory 74.74% <ø> (ø)
packages/model-bank 99.86% <ø> (ø)
packages/model-runtime 84.19% <ø> (-0.01%) ⬇️
packages/prompts 69.24% <ø> (ø)
packages/python-interpreter 92.90% <ø> (ø)
packages/ssrf-safe-fetch 0.00% <ø> (ø)
packages/utils 90.14% <ø> (ø)
packages/web-crawler 88.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Store 65.70% <90.00%> (+<0.01%) ⬆️
Services 52.19% <100.00%> (ø)
Server 66.31% <ø> (-0.01%) ⬇️
Libs 52.83% <ø> (ø)
Utils 91.07% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@arvinxx arvinxx merged commit 0486be4 into canary Apr 12, 2026
30 of 31 checks passed
@arvinxx arvinxx deleted the fix/context-engine-non-string-content-guard branch April 12, 2026 11:27
canisminor1990 added a commit that referenced this pull request Apr 16, 2026
# 🚀 LobeHub v2.1.50 (20260416)

**Release Date:** April 16, 2026\
**Since v2.1.49:** 107 commits · 101 merged PRs · 13 contributors

> This weekly release focuses on improving runtime stability and gateway
execution consistency, while making Home/Recents workflows faster to
navigate and easier to manage in daily use.

---

## ✨ Highlights

- **Server-side Human Approval Flow** — Agent runtime now supports more
reliable approve/reject/reject-continue handling in gateway mode,
reducing stalled execution paths in long-running tasks. (#13829, #13863,
#13873)

- **Message Gateway End-to-End Hardening** — Gateway message flow, queue
handling, tool callback routing, and stop interruption behavior were
strengthened for better execution continuity. (#13761, #13816, #13820,
#13815)

- **Client Tool Execution in Gateway Mode** — Client-executor tools now
run more predictably across gateway and desktop callers, with improved
executor dispatch behavior. (#13792, #13790)

- **Home / Recents / Sidebar Upgrade** — Sidebar layout, custom sort,
recents operations, and profile actions were improved to reduce
navigation friction in active sessions. (#13719, #13812, #13723, #13739,
#13878, #13734)

- **Agent Workspace and Documents Expansion** — Working panel and agent
document workflows were expanded and polished for better day-to-day
agent operations. (#13766, #13857)

- **Provider and Model Compatibility Improvements** — Added GLM-5.1
support and refined model/provider edge-case handling, including schema
and error-path fixes. (#13757, #13806, #13736, #13740)

---

## 🏗️ Core Agent & Architecture

### Agent runtime and intervention lifecycle

- Added server-side human approval and improved runtime coordination
across approve/reject decision paths. (#13829, #13863)
- Improved interrupted-task handling and operation lifecycle consistency
to reduce half-finished runtime states. (#13714)
- Refined error classification and payload propagation so downstream
surfaces receive clearer actionable errors. (#13736, #13740)

### Execution model and dispatch behavior

- Introduced executor-aware runtime behavior to better separate
client/server tool execution semantics. (#13758)
- Improved tool/plugin resolution and manifest handling to avoid runtime
failures on malformed inputs. (#13856, #13840, #13807)

---

## 📱 Gateway & Platform Integrations

- Added message gateway support and strengthened queue/error behavior
for more stable cross-channel execution. (#13761, #13816, #13820)
- Improved gateway callback pipeline with protocol and API additions for
`tool_execute` / `tool_result`. (#13762, #13764, #13765)
- Improved bot/channel reliability and DM/slash handling in
Discord-related paths. (#13805, #13724)

---

## 🖥️ CLI & User Experience

- Improved CLI reliability across message/topic operations and
build/minify-related paths. (#13731, #13888)
- Added image-to-video options and improved command behavior for
generation workflows. (#13788)
- Improved desktop runtime behavior for remote fetch and Linux
notification urgency handling. (#13789, #13782)

---

## 🔧 Tooling

- Extracted gateway stream client into `@lobechat/agent-gateway-client`
to centralize protocol usage and reduce duplication. (#13866)
- Improved built-in tool coverage and runtime support, including GTD
server runtime and missing lobe-kb tools. (#13854, #13876)
- Updated skill and frontmatter consistency in workflow tooling.
(#13730)

---

## 🔒 Security & Reliability

- **Security:** Strengthened API key WS auth behavior and safer
serverUrl forwarding in gateway-related auth paths. (#13824)
- **Reliability:** Reduced runtime stalls by improving gateway
stop/interrupt and approval-state routing behavior. (#13815, #13863,
#13873)
- **Reliability:** Added defensive guards for malformed tool manifests
and non-string content edge cases. (#13856, #13753)

---

## 👥 Contributors

**101 merged PRs** from **13 contributors** across **107 commits**.

### Community Contributors

- @arvinxx - Runtime, gateway, and execution reliability improvements
- @Innei - Navigation, workflow UX, and desktop/CLI refinements
- @rdmclin2 - Sidebar, recents, and channel behavior updates
- @ONLY-yours - Tooling/runtime fixes and model execution compatibility
- @tjx666 - Model support and release/tooling maintenance
- @nekomeowww - Memory and search-path stability fixes
- @cy948 - CLI indexing and command flow fixes
- @octo-patch - Local system runtime edge-case fixes
- @djthread - Desktop runtime request reliability improvements
- @rivertwilight - Documentation and changelog updates
- @sudongyuer - Subscription/mobile support improvements
- @Zhouguanyang - Provider/model configuration correctness fixes
- @lobehubbot - Translation and maintenance automation support

---

**Full Changelog**: v2.1.49...v2.1.50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant