Skip to content

Session repair (repairSessionFileIfNeeded) does not sanitize empty text blocks in user messages #73472

@waiT-Chi

Description

@waiT-Chi

Bug Description

repairSessionFileIfNeeded in session-file-repair.ts only checks assistant messages for empty content (isAssistantEntryWithEmptyContent), but does not sanitize user messages containing empty text content blocks like {"type": "text", "text": ""}.

When such a block exists in a user message, every subsequent API call that includes the session history is rejected by the Claude API with:

messages: text content blocks must be non-empty

This creates a permanent failure loop: the session is broken, repairSessionFileIfNeeded runs but doesn't detect/fix the user message, and the user gets ⚠️ Something went wrong on every message — even after /new won't help if the old session is still loaded.

Steps to Reproduce

  1. Send an empty message via Telegram (or trigger an empty text block in user content through any channel)
  2. A session JSONL entry is created with: {"type":"message", "message":{"role":"user", "content":[{"type":"text","text":""}]}}
  3. All subsequent messages in this session fail with: ⚠️ Something went wrong while processing your request
  4. /new does not help if the session with the empty block is still loaded
  5. repairSessionFileIfNeeded runs repeatedly but never fixes it — it only checks role === "assistant"

Expected Behavior

repairSessionFileIfNeeded should also sanitize user messages:

  • Detect {"type":"text","text":""} in user message content blocks
  • Either remove the empty text block or replace it with a placeholder
  • Alternatively, add input validation to prevent empty text blocks from being written to session files in the first place

Observed Behavior

  • Repair logic in isAssistantEntryWithEmptyContent() explicitly filters for role === "assistant" only
  • Discord channel has "drop message (empty content)" logic, but Telegram channel does not
  • Error log shows the repair running in a loop: repair → API call → reject → repair → repeat

Environment

  • OpenClaw version: latest (npm global install)
  • Channel: Telegram
  • Model: Claude (Anthropic API)
  • OS: macOS ARM (Apple Silicon)

Related Issues

Suggested Fix

In session-file-repair.ts, extend the repair logic to cover all roles:

// Current: only checks assistant
function isAssistantEntryWithEmptyContent(entry) {
  return entry.message?.role === "assistant" && ...
}

// Suggested: also check user messages for empty text blocks
function hasEmptyTextBlock(entry) {
  const content = entry.message?.content;
  if (!Array.isArray(content)) return false;
  return content.some(block => block.type === "text" && block.text === "");
}

Additionally, consider adding input validation in the Telegram channel handler (similar to Discord's "drop message (empty content)" logic) to prevent empty messages from being written to session files at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions