#18893: fix(message): use currentMessageId for react fallback and suppress recoverable react warnings
agents
size: M
Cluster:
Message Handling Improvements
## Summary
Improve agent-initiated `message(action=react)` behavior by wiring `currentMessageId` through the embedded tool pipeline and using it as the fallback source when `messageId` is missing.
Also suppresses recoverable react input warnings (for example `messageId required`) from user-visible payloads to avoid noisy error text leaks.
## Changes
- Add `currentMessageId` to `ChannelThreadingToolContext` and threading context builder.
- In `runMessageAction`, for `react`, fill `params.messageId` from `toolContext.currentMessageId` when missing.
- Wire `currentMessageId` through embedded runner/tool creation path:
- `run/params.ts`, `run.ts`, `run/attempt.ts`
- `pi-tools.ts`, `openclaw-tools.ts`, `message-tool.ts`
- Add/adjust tests:
- `message-action-runner.test.ts`
- `reply-plumbing.test.ts`
- `message-tool.e2e.test.ts`
- `payloads.e2e.test.ts`
## Validation
- `pnpm vitest run src/infra/outbound/message-action-runner.test.ts src/auto-reply/reply/reply-plumbing.test.ts`
- `pnpm vitest run --config vitest.e2e.config.ts src/agents/pi-embedded-runner/run/payloads.e2e.test.ts src/agents/tools/message-tool.e2e.test.ts`
- `pnpm build`
Refs #18154
Refs #17782
Refs #17651
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR wires `currentMessageId` through the embedded tool pipeline so that `message(action=react)` can use it as a fallback when the LLM omits `messageId`. It also adds a suppression mechanism for recoverable react input errors in the payload builder to avoid leaking noisy warnings into user-facing chats.
- Adds `currentMessageId` to `ChannelThreadingToolContext` and propagates it through `buildThreadingToolContext`, `RunEmbeddedPiAgentParams`, `createOpenClawCodingTools`, `createOpenClawTools`, `createMessageTool`, and the embedded runner/attempt pipeline.
- In `runMessageAction`, fills `params.messageId` from `toolContext.currentMessageId` when the action is `react` and `messageId` is missing — this is the core behavior fix.
- Adds `isRecoverableMessageReactInputError` in `payloads.ts` to suppress user-visible warning payloads for react input errors. **However, the suppression is overly broad**: it matches any `RECOVERABLE_TOOL_ERROR_KEYWORDS` (e.g., "required", "missing", "invalid") for react actions, not just `messageId`-related ones. This could silently hide legitimate errors like Discord's `"emoji required"` when the emoji string is empty.
- Tests cover the new `messageId` inference, context forwarding, and suppression behavior, though the suppression test only exercises the `"messageId required"` case.
<h3>Confidence Score: 3/5</h3>
- The core `messageId` fallback logic is correct and well-tested, but the error suppression in `payloads.ts` is too broad and could hide legitimate react errors.
- The plumbing of `currentMessageId` through the pipeline (12 of 14 files) is clean, consistent with existing patterns (`currentChannelId`, `currentThreadTs`), and well-tested. The `runMessageAction` fallback logic is correctly placed and guarded. However, `isRecoverableMessageReactInputError` suppresses all recoverable-keyword errors for react actions, not just `messageId`-specific ones — this could silently hide errors like "emoji required" from Discord. Score reflects the one meaningful logic concern in an otherwise well-executed PR.
- `src/agents/pi-embedded-runner/run/payloads.ts` — the `isRecoverableMessageReactInputError` function's error matching is too broad and should be narrowed to `messageId`-related errors specifically.
<sub>Last reviewed commit: 42a1f41</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#18408: fix(message): support react current alias and suppress leaked react...
by sggolakiya · 2026-02-16
85.7%
#20236: fix(telegram): make reaction handling soft-fail and message-id resi...
by PeterShanxin · 2026-02-18
80.0%
#18466: fix: suppress recoverable mutating tool errors when agent already r...
by stijnhoste · 2026-02-16
77.4%
#19632: fix: suppressToolErrors now suppresses exec tool failure notifications
by Gitjay11 · 2026-02-18
73.7%
#23723: feat(message): improve send param ergonomics and actionable routing...
by SmithLabsLLC · 2026-02-22
73.7%
#21132: fix: allow message(action='read') in isolated/cron sessions + add H...
by matt-bedda · 2026-02-19
73.3%
#17070: fix(telegram): Outbound: ignore empty legacy target fields
by yhw2003 · 2026-02-15
73.0%
#19235: fix(telegram): tool error warnings no longer overwrite streamed rep...
by gatewaybuddy · 2026-02-17
72.6%
#21271: fix(commands): pass channel/capabilities/shell/os to runtime in com...
by evansantos · 2026-02-19
72.4%
#13282: fix(agents): instruct agent not to retry lost tool results
by thebtf · 2026-02-10
72.4%