Skip to content

fix(feishu): stop typing-indicator log spam and stuck emoji on message-not-found#27525

Closed
byungsker wants to merge 1 commit into
openclaw:mainfrom
byungsker:fix/feishu-typing-log-spam-and-stuck-emoji
Closed

fix(feishu): stop typing-indicator log spam and stuck emoji on message-not-found#27525
byungsker wants to merge 1 commit into
openclaw:mainfrom
byungsker:fix/feishu-typing-log-spam-and-stuck-emoji

Conversation

@byungsker

Copy link
Copy Markdown

Problem

Fixes #27418

Two related bugs in the Feishu typing-indicator (reaction emoji):

  1. Log spamaddTypingIndicator silently caught failures and printed a console.log on every keepalive tick (every 3 s). When the target message no longer exists (Feishu error code 231003), the error repeated indefinitely.

  2. Typing emoji stuck on message – the keepalive called addTypingIndicator on every tick. Because the reaction already existed (or the call failed), the SDK returned reactionId: null. The dispatcher overwrote typingState with { reactionId: null }, so removeTypingIndicator had nothing to delete, leaving the Typing emoji on the user's message permanently.

Root cause

// Every 3 s the keepalive fired start(), which called addTypingIndicator().
// addTypingIndicator caught all errors and returned { reactionId: null }.
// typingState was overwritten → removeTypingIndicator was a no-op.

Fix

extensions/feishu/src/typing.ts

  • Remove internal console.log / try-catch from addTypingIndicator and removeTypingIndicator; errors now propagate so structured error handlers are used.
  • Export isFeishuMessageNotFoundError() helper that detects Feishu error code 231003.

extensions/feishu/src/reply-dispatcher.ts

  • Add typingDisabled flag: set on the first 231003 error, causing all subsequent keepalive ticks to skip the API call (no more log spam).
  • Guard start() with if (typingState?.reactionId) return so the keepalive never overwrites a valid reactionId with null — ensuring removeTypingIndicator can always clean up properly.
  • Null typingState before awaiting removal to avoid a race where a second stop call finds stale state.

Tests

Added extensions/feishu/src/typing.test.ts with 6 unit tests for isFeishuMessageNotFoundError.

…e-not-found

- Remove internal console.log from addTypingIndicator/removeTypingIndicator;
  errors now propagate so callers handle them via the structured onStartError /
  onStopError paths instead of raw console output.

- Add isFeishuMessageNotFoundError() helper that detects Feishu error code
  231003 ("The message is not found, maybe not exist or deleted").

- In reply-dispatcher, introduce typingDisabled flag: the first time start()
  receives a 231003 error the flag is set and all subsequent keepalive ticks
  are skipped, eliminating the 3-second log spam seen in openclaw#27418.

- Guard start() so it skips when typingState.reactionId is already set.
  Previously the keepalive overwrote typingState with null on every tick
  (because addTypingIndicator failed silently), causing removeTypingIndicator
  to find no reactionId and leaving the Typing emoji permanently on the
  user's message.

Fixes openclaw#27418
@greptile-apps

greptile-apps Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two related bugs in the Feishu typing indicator implementation that caused log spam and stuck emoji reactions. The changes improve error handling by removing silent console.log calls and instead propagating errors to structured handlers. Key improvements include:

  • Removed internal try-catch blocks from addTypingIndicator and removeTypingIndicator, allowing errors to propagate to proper error handlers
  • Added isFeishuMessageNotFoundError helper to detect Feishu error code 231003 (message deleted/expired)
  • Introduced typingDisabled flag that stops retry attempts when message no longer exists, preventing log spam from keepalive ticks
  • Added guard if (typingState?.reactionId) return to prevent keepalive from overwriting valid reaction IDs with null
  • Fixed race condition by nulling typingState before awaiting removal in stop() callback
  • Added comprehensive unit tests for the error detection helper

The implementation correctly handles the error propagation flow: addTypingIndicator/removeTypingIndicator throw → errors caught by SDK's typing callback wrapper → routed to onStartError/onStopError → handled appropriately (disable retries for 231003, log other errors). The solution is well-designed and addresses the root causes described in #27418.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-structured and address specific, documented bugs. The error handling refactor follows proper patterns by letting errors propagate to structured handlers rather than silent catches. The logic for preventing duplicate reactions and disabling retries on permanent failures is sound. Tests provide good coverage of the error detection helper. The changes are scoped to fixing the specific issues without introducing unnecessary refactoring.
  • No files require special attention

Last reviewed commit: a1889d1

@Takhoffman

Copy link
Copy Markdown
Contributor

PR #27525 is superseded by commit 32ee2f0:
32ee2f0

That landed the current Feishu typing loop-breaker path and is the canonical fix line on main.

@Takhoffman Takhoffman closed this Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu close:superseded PR close reason size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feishu] Typing indicator causes log spam and doesn't work properly

2 participants