* fix(telegram): validate photo dimensions before sendPhoto
Prevents PHOTO_INVALID_DIMENSIONS errors by checking image dimensions
against Telegram Bot API requirements before calling sendPhoto.
If dimensions exceed limits (width + height > 10,000px), automatically
falls back to sending as document instead of crashing with 400 error.
Tested in production (openclaw 2026.3.13) where this error occurred:
[telegram] tool reply failed: GrammyError: Call to 'sendPhoto' failed!
(400: Bad Request: PHOTO_INVALID_DIMENSIONS)
Uses existing sharp dependency to read image metadata. Gracefully
degrades if sharp fails (lets Telegram handle validation, backward
compatible behavior).
Closes: #XXXXX (will reference OpenClaw issue if one exists)
* fix(telegram): validate photo aspect ratio
* refactor: use shared telegram image metadata
* fix: fail closed on telegram image metadata
* fix: preflight invalid telegram photos (#52545) (thanks @hnshah)
---------
Co-authored-by: Bob Shah <bobshah@Macs-Mac-Studio.local>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Groups configured with groupPolicy: open are expected to respond to all
messages. Previously, requireMention defaulted to true regardless of
groupPolicy, causing image (and other non-text) messages to be silently
dropped because they cannot carry @-mentions.
Fix: when groupPolicy is 'open' and requireMention is not explicitly
configured, resolve it to false instead of true. Users who want
mention-required behaviour in open groups can still set requireMention: true
explicitly.
Adds three regression tests covering the new default, explicit override, and
the unchanged allowlist-policy behaviour.
Closes#52553
Move cleanup() after disconnect() in waitForDiscordGatewayStop so the
error listener is still active during disconnect. Add a safety error
listener in the lifecycle finally block to suppress late errors emitted
by Carbon during teardown.
Fixes the "Max reconnect attempts (0) reached after code 1006" uncaught
exception that kills the entire gateway process when a Discord WebSocket
drops and reconnection fails.
* fix(telegram): improve error messages for 403 bot not member errors
- Detect 403 'bot is not a member' errors specifically
- Provide actionable guidance for users to fix the issue
- Fixes#48273 where outbound sendMessage fails with 403
Root cause:
When a Telegram bot tries to send a message to a channel/group it's not
a member of, the API returns 403 'bot is not a member of the channel chat'.
The error message was not clear about how to fix this.
Fix:
1. Detect 403 errors in wrapTelegramChatNotFoundError
2. Provide clear error message explaining the issue
3. Suggest adding the bot to the channel/group
* fix(telegram): fix regex precedence for 403 error detection
- Group alternatives correctly: /403.*(bot.*not.*member|bot was blocked)/i
- Require 403 for both alternatives (previously bot.*blocked matched any error)
- Update error message to cover both scenarios
- Fixes Greptile review feedback
* fix(telegram): correct regex alternation precedence for 403 errors
- Fix: /403.*(bot.*not.*member|bot was blocked)/ → /403.*(bot.*not.*member|bot.*blocked)/
- Ensures 403 requirement applies to both alternatives
- Fixes Greptile review comment on PR #48650
* fix(telegram): add 'bot was kicked' to 403 error regex and message
* fix(telegram): preserve membership delivery errors
* fix: improve Telegram 403 membership delivery errors (#53635) (thanks @w-sss)
---------
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
When OpenClaw restarts under load, the Feishu bot-info probe
(`/open-apis/bot/v3/info`) can exceed the 10-second timeout due to
event-loop contention during channel initialization. This leaves
`botOpenId` empty, causing `checkBotMentioned()` to return `false`
for every group message — silently dropping them all while DMs
continue to work fine.
Two fixes:
1. **Increase startup probe timeout from 10s to 30s** and make it
configurable via `OPENCLAW_FEISHU_STARTUP_PROBE_TIMEOUT_MS` env var.
The previous 10s budget was too tight when multiple channels
(Slack, Discord, Feishu) initialize concurrently.
2. **Graceful degradation in `checkBotMentioned()`**: when `botOpenId`
is unknown, return `true` (assume mentioned) instead of `false`.
This prevents group messages from being silently discarded when the
probe fails for any reason. The trade-off is that the bot may
respond to non-@-mentioned messages temporarily until the next
successful probe, which is far preferable to total silence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `createMessageToolCardSchema()` helper returned a bare `Type.Object()`
which TypeBox treats as required when merged into the parent tool schema via
`Type.Object({ card: ... })`. This caused schema validation to reject
media-only sends on Feishu and MSTeams with "must have required property
card", even though the implementation correctly treats card as optional.
Wrap the return value in `Type.Optional()` so the card field is excluded
from the JSON Schema `required` array. Fixes the catch-22 where omitting
card fails validation and including an empty card triggers the runtime
"does not support card with media" guard.
Closes#53697
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>