Feature/telegram error policy#34498
Conversation
…sages ## Summary - Problem: When OpenClaw hits provider/rate limits, it can post the same error response repeatedly in active group chats - Why it matters: Creates spam, degrades trust, disrupts conversation flow in groups - What changed: Added errorPolicy (always|once|silent) and errorCooldownMs config at group/direct/topic/account levels - What did NOT change: Error handling in DMs (still sends all errors), core reply logic unchanged ## Change Type - [x] Feature ## Scope - [x] Integrations (Telegram channel) ## Linked Issue/PR - Related openclaw#34114 ## User-visible / Behavior Changes - New config: channels.telegram.errorPolicy (always/once/silent) - New config: channels.telegram.errorCooldownMs (default: 4 hours) - New config: channels.telegram.groups.<groupId>.errorPolicy (per-group override) ## Security Impact - New permissions/capabilities? No - Secrets/tokens handling changed? No - New/changed network calls? No - Command/tool execution surface changed? No - Data access scope changed? No ## Repro + Verification ### Environment - OS: Linux - Integration/channel: Telegram ### Steps 1. Configure errorPolicy: "once" in telegram channel config 2. Trigger rate limit error 3. Send another message to trigger same error ### Expected - First error is shown - Subsequent errors during cooldown are suppressed ### Actual - Behavior verified in code flow (in-memory cooldown tracking) ## Evidence - [x] Code changes implement the policy logic ## Human Verification - Verified scenarios: Code compiles, logic correctly gates error display - Edge cases checked: Group config takes precedence over channel config - What you did not verify: Full E2E testing with live Telegram bot ## Compatibility / Migration - Backward compatible? Yes (default is "always" which is current behavior) - Config/env changes? Yes (new optional config) - Migration needed? No ## Failure Recovery - How to disable/revert: Set errorPolicy: "always" or remove config - Files/config to restore: src/config/zod-schema.providers-core.ts, src/telegram/bot-message-dispatch.ts, src/telegram/error-policy.ts - Known bad symptoms: If errorPolicy not set, defaults to "always" (current behavior) ## Risks and Mitigations - Risk: In-memory cooldown store resets on restart - Mitigation: Expected for this feature; user can trigger fresh error after restart AI-assisted (light testing)
Greptile SummaryThis PR introduces a configurable error-suppression policy ( Key findings:
Confidence Score: 2/5
Last reviewed commit: 313ee36 |
| if (shouldSuppressTelegramError({ | ||
| chatId, | ||
| cooldownMs: errorPolicy.cooldownMs, | ||
| errorMessage: String(err), | ||
| })) { | ||
| return; |
There was a problem hiding this comment.
"always" policy incorrectly suppresses errors
shouldSuppressTelegramError is called unconditionally for both "always" and "once" policies (only "silent" is filtered out before this). On the second error from the same chat within the cooldown window, shouldSuppressTelegramError returns true and the error is swallowed — even when errorPolicy.policy === "always". This directly contradicts the semantics of the "always" policy.
The call must be guarded to only run for the "once" policy:
| if (shouldSuppressTelegramError({ | |
| chatId, | |
| cooldownMs: errorPolicy.cooldownMs, | |
| errorMessage: String(err), | |
| })) { | |
| return; | |
| if (errorPolicy.policy === "once" && shouldSuppressTelegramError({ | |
| chatId, | |
| cooldownMs: errorPolicy.cooldownMs, | |
| errorMessage: String(err), | |
| })) { | |
| return; | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/bot-message-dispatch.ts
Line: 630-635
Comment:
**"always" policy incorrectly suppresses errors**
`shouldSuppressTelegramError` is called unconditionally for both `"always"` and `"once"` policies (only `"silent"` is filtered out before this). On the second error from the same chat within the cooldown window, `shouldSuppressTelegramError` returns `true` and the error is swallowed — even when `errorPolicy.policy === "always"`. This directly contradicts the semantics of the `"always"` policy.
The call must be guarded to only run for the `"once"` policy:
```suggestion
if (errorPolicy.policy === "once" && shouldSuppressTelegramError({
chatId,
cooldownMs: errorPolicy.cooldownMs,
errorMessage: String(err),
})) {
return;
}
```
How can I resolve this? If you propose a fix, please make it concise.| export function resolveTelegramErrorPolicy(params: { | ||
| cfg: OpenClawConfig; | ||
| channel: ChannelId; | ||
| accountId?: string | null; | ||
| chatId?: string | number | null; | ||
| isGroup?: boolean; | ||
| }): { | ||
| policy: TelegramErrorPolicy; | ||
| cooldownMs: number; | ||
| } { | ||
| const { cfg, channel, accountId, chatId, isGroup = false } = params; |
There was a problem hiding this comment.
accountId parameter is accepted but never used
accountId is part of the function signature and is destructured on line 40, but it is never referenced in the function body. If the intent is to support per-account error policy overrides (e.g. when multiple Telegram accounts are configured under the same channel key), this is currently a no-op and the parameter is misleading. If per-account resolution is out of scope, the parameter should be removed to avoid confusion.
| export function resolveTelegramErrorPolicy(params: { | |
| cfg: OpenClawConfig; | |
| channel: ChannelId; | |
| accountId?: string | null; | |
| chatId?: string | number | null; | |
| isGroup?: boolean; | |
| }): { | |
| policy: TelegramErrorPolicy; | |
| cooldownMs: number; | |
| } { | |
| const { cfg, channel, accountId, chatId, isGroup = false } = params; | |
| export function resolveTelegramErrorPolicy(params: { | |
| cfg: OpenClawConfig; | |
| channel: ChannelId; | |
| chatId?: string | number | null; | |
| isGroup?: boolean; | |
| }): { | |
| policy: TelegramErrorPolicy; | |
| cooldownMs: number; | |
| } { | |
| const { cfg, channel, chatId, isGroup = false } = params; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/error-policy.ts
Line: 30-40
Comment:
**`accountId` parameter is accepted but never used**
`accountId` is part of the function signature and is destructured on line 40, but it is never referenced in the function body. If the intent is to support per-account error policy overrides (e.g. when multiple Telegram accounts are configured under the same channel key), this is currently a no-op and the parameter is misleading. If per-account resolution is out of scope, the parameter should be removed to avoid confusion.
```suggestion
export function resolveTelegramErrorPolicy(params: {
cfg: OpenClawConfig;
channel: ChannelId;
chatId?: string | number | null;
isGroup?: boolean;
}): {
policy: TelegramErrorPolicy;
cooldownMs: number;
} {
const { cfg, channel, chatId, isGroup = false } = params;
```
How can I resolve this? If you propose a fix, please make it concise.| // Check group-specific config first (if in a group and chatId is available) | ||
| if (isGroup && chatId) { | ||
| const chatIdStr = String(chatId); | ||
| const groupConfig = channelConfig.groups?.[chatIdStr]; | ||
| if (groupConfig?.errorPolicy) { | ||
| return { | ||
| policy: groupConfig.errorPolicy, | ||
| cooldownMs: groupConfig.errorCooldownMs ?? DEFAULT_ERROR_COOLDOWN_MS, | ||
| }; | ||
| } | ||
| } |
There was a problem hiding this comment.
Topic-level errorPolicy configured in schema is never consulted
TelegramTopicSchema in zod-schema.providers-core.ts gains an errorPolicy field (and the PR description explicitly lists "topic" as a supported level), but resolveTelegramErrorPolicy only checks group-level and channel-level config. Any value a user sets under channels.telegram.groups.<groupId>.topics.<topicId>.errorPolicy is silently ignored.
Either the resolution logic here needs a topic-aware path (requiring a topicId parameter), or the errorPolicy field should be removed from TelegramTopicSchema to avoid a dead configuration key that creates a false expectation for users.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/error-policy.ts
Line: 48-58
Comment:
**Topic-level `errorPolicy` configured in schema is never consulted**
`TelegramTopicSchema` in `zod-schema.providers-core.ts` gains an `errorPolicy` field (and the PR description explicitly lists "topic" as a supported level), but `resolveTelegramErrorPolicy` only checks group-level and channel-level config. Any value a user sets under `channels.telegram.groups.<groupId>.topics.<topicId>.errorPolicy` is silently ignored.
Either the resolution logic here needs a topic-aware path (requiring a `topicId` parameter), or the `errorPolicy` field should be removed from `TelegramTopicSchema` to avoid a dead configuration key that creates a false expectation for users.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 313ee36b66
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (shouldSuppressTelegramError({ | ||
| chatId, | ||
| cooldownMs: errorPolicy.cooldownMs, | ||
| errorMessage: String(err), | ||
| })) { |
There was a problem hiding this comment.
Skip cooldown suppression when policy is "always"
This suppression check runs for every non-silent policy, so the default errorPolicy: "always" still enters cooldown: after the first failure in a chat, subsequent failures inside errorCooldownMs return early and never reach markNonSilentFailure(). In practice, repeated provider/rate-limit failures stop producing fallback error responses, which is a behavior change from the previous "always report" default.
Useful? React with 👍 / 👎.
| } { | ||
| const { cfg, channel, accountId, chatId, isGroup = false } = params; | ||
|
|
||
| const channelConfig = cfg.channels?.[channel] as TelegramAccountConfig | undefined; |
There was a problem hiding this comment.
Resolve error policy from the selected Telegram account
The resolver receives accountId but does not use it, and instead reads only cfg.channels[channel]; this means channels.telegram.accounts.<id>.errorPolicy/errorCooldownMs (and that account's group overrides) are ignored in multi-account deployments. The dispatcher passes route.accountId, but account-specific policy cannot take effect with the current lookup.
Useful? React with 👍 / 👎.
| // Check group-specific config first (if in a group and chatId is available) | ||
| if (isGroup && chatId) { | ||
| const chatIdStr = String(chatId); | ||
| const groupConfig = channelConfig.groups?.[chatIdStr]; |
There was a problem hiding this comment.
Honor wildcard group error-policy overrides
Group policy lookup only checks the exact chat id and never falls back to groups["*"], so a global group override for errorPolicy/errorCooldownMs will be silently ignored. Telegram group config elsewhere already supports wildcard fallback, so this inconsistency will surprise operators who configure catch-all group behavior.
Useful? React with 👍 / 👎.
Use the accountId parameter to check account-level config first, then group-level config within the account, before falling back to channel-level. This addresses the PR review comment about accountId being unused. AI-assisted
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6339b5d40c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (isGroup && chatId) { | ||
| const chatIdStr = String(chatId); | ||
| const groupConfig = accountConfig.groups?.[chatIdStr]; |
There was a problem hiding this comment.
Resolve DM/topic-specific error policy overrides
resolveTelegramErrorPolicy only performs per-chat lookups inside the isGroup branch and never evaluates direct or topic-level settings, so configs like channels.telegram.direct.<id>.errorPolicy and ...topics.<id>.errorPolicy are accepted by schema but have no runtime effect. This means operators cannot actually enable silent/once behavior for DMs or per-topic threads even though those keys were introduced in this change.
Useful? React with 👍 / 👎.
| if (groupConfig?.errorPolicy) { | ||
| return { | ||
| policy: groupConfig.errorPolicy, | ||
| cooldownMs: groupConfig.errorCooldownMs ?? DEFAULT_ERROR_COOLDOWN_MS, | ||
| }; |
There was a problem hiding this comment.
Allow cooldown overrides without redefining policy
The resolver only returns group/account overrides when errorPolicy is present, so errorCooldownMs is ignored if it is configured alone. In practice, if a channel-level policy is already set (for example once), setting only groups.<id>.errorCooldownMs or accounts.<id>.errorCooldownMs does nothing, which silently breaks cooldown-only overrides and forces redundant policy duplication.
Useful? React with 👍 / 👎.
| errorMessage?: string; | ||
| }): boolean { | ||
| const { chatId, cooldownMs, errorMessage } = params; | ||
| const chatIdStr = String(chatId); |
There was a problem hiding this comment.
Scope cooldown tracking key by account identity
Cooldown entries are keyed only by chatId, so failures from one Telegram account suppress error reporting for any other account that serves the same chat ID during the cooldown window. This creates cross-account interference in multi-account deployments (e.g., two bots in one group), where one route's failure state incorrectly affects another route's visibility.
Useful? React with 👍 / 👎.
Use Omit to properly type the channel config that includes accounts map, matching TelegramConfigSchema structure. AI-assisted
|
Updated code based on the Greptile review. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 655bd28f18
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (isSilentErrorPolicy(errorPolicy.policy)) { | ||
| return; |
There was a problem hiding this comment.
Preserve runtime logging for silent error policy
Returning immediately for silent skips runtime.error?.(...), and this callback is the only place delivery exceptions are logged in this dispatch path. In chats configured as silent, transport/provider failures therefore disappear from operator logs entirely, which makes production outages hard to detect and diagnose even though only user-facing error messages were meant to be suppressed.
Useful? React with 👍 / 👎.
| if (now - entry.lastErrorTime < cooldownMs) { | ||
| // Within cooldown - suppress this error | ||
| return true; |
There was a problem hiding this comment.
Differentiate cooldown suppression by error message
shouldSuppressTelegramError suppresses all failures during the cooldown window using only lastErrorTime, so a later unrelated failure in the same chat is dropped after any first error. This means a transient first error can mask a new incident (for example, an auth/config break) for up to errorCooldownMs, despite the function already receiving and storing errorMessage.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c46da932e5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Check per-account config first (when accountId is provided) | ||
| const normalizedAccountId = accountId ?? null; | ||
| if (normalizedAccountId) { | ||
| const accountConfig = channelConfig.accounts?.[normalizedAccountId]; |
There was a problem hiding this comment.
Look up account overrides case-insensitively
resolveTelegramErrorPolicy fetches account overrides with a direct key lookup (channelConfig.accounts?.[normalizedAccountId]), but Telegram account IDs are resolved case-insensitively elsewhere (via resolveAccountEntry in account routing). If a config uses mixed-case account keys and runtime routing passes a normalized lowercase ID, account-level errorPolicy/errorCooldownMs are silently ignored and channel defaults are used instead.
Useful? React with 👍 / 👎.
| return { | ||
| policy: groupConfig.errorPolicy, | ||
| cooldownMs: groupConfig.errorCooldownMs ?? DEFAULT_ERROR_COOLDOWN_MS, | ||
| }; |
There was a problem hiding this comment.
Cascade cooldown from parent scopes before defaulting
When a scoped override sets errorPolicy but omits errorCooldownMs, the resolver immediately falls back to DEFAULT_ERROR_COOLDOWN_MS instead of inheriting a configured parent cooldown (account or channel). This means a global channels.telegram.errorCooldownMs is unexpectedly bypassed as soon as a group/account policy is customized, producing a 4-hour cooldown even when operators configured a different base cooldown.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a1eb8eb8d9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!entry) { | ||
| // First error - record it and don't suppress | ||
| errorCooldownStore.set(chatIdStr, { | ||
| lastErrorTime: now, | ||
| errorMessage, | ||
| }); |
There was a problem hiding this comment.
Evict stale Telegram error cooldown entries
Each first delivery failure adds a chatId entry to the process-wide errorCooldownStore, but there is no code path that ever deletes entries after their cooldown window; later calls only overwrite timestamps for the same key. In long-lived gateways that see one-off errors across many chats, this map grows monotonically for the lifetime of the process and can become an avoidable memory leak.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ff756ef19
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Check group-specific config at channel level (for default account) | ||
| if (isGroup && chatId) { | ||
| const chatIdStr = String(chatId); | ||
| const groupConfig = channelConfig.groups?.[chatIdStr]; |
There was a problem hiding this comment.
Skip channel group fallback for named accounts
This fallback applies channels.telegram.groups for every account, not just the default account. In multi-account setups, mergeTelegramAccountConfig intentionally does not inherit channel-level groups into named accounts, but this code bypasses that rule and can make one account's group errorPolicy/errorCooldownMs suppress errors for another account in the same chat. That creates cross-account policy bleed and unexpected silent behavior in shared groups.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f2269f1bb
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| errorMessage?: string; | ||
| }): boolean { | ||
| const { chatId, cooldownMs, errorMessage } = params; | ||
| const chatIdStr = String(chatId); |
There was a problem hiding this comment.
Key Telegram cooldown suppression by thread id
shouldSuppressTelegramError uses only chatId as the cooldown key, so all forum topics (and DM topics) inside the same Telegram chat share one suppression window. With errorPolicy: "once", a transient failure in topic A will suppress subsequent failures in topic B until cooldown expires, which hides independent delivery incidents across threads that are otherwise routed separately in Telegram.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11a9c08f87
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| import { | ||
| isSilentErrorPolicy, | ||
| resolveTelegramErrorPolicy, | ||
| shouldSuppressTelegramError, | ||
| } from "./error-policy.js"; |
There was a problem hiding this comment.
Restore exec-approval helper import
This import block drops shouldSuppressLocalTelegramExecApprovalPrompt, but the dispatcher still calls that symbol in the delivery path; when a reply payload is handled, the missing binding causes a ReferenceError and aborts Telegram dispatch before sending the message. Because this is in the hot path for normal replies, it can break delivery broadly whenever this module runs without a strict type-check gate.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b4bca48d1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| onError: (err, info) => { | ||
| const errorPolicy = resolveTelegramErrorPolicy({ | ||
| cfg, | ||
| channel: "telegram", |
There was a problem hiding this comment.
Apply error policy to delivered error payloads
This policy is only consulted inside the dispatcher onError callback, but that callback runs only when deliver throws (src/auto-reply/reply/reply-dispatcher.ts catches await options.deliver(...) failures). Provider/rate-limit failures that are turned into normal isError reply payloads and delivered successfully never hit this path, so repeated provider error messages are still sent to chats and the new anti-spam behavior does not activate for its primary scenario.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b768b2997
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| errorPolicy: TelegramErrorPolicySchema, | ||
| errorCooldownMs: z.number().int().nonnegative().optional(), |
There was a problem hiding this comment.
Sync Telegram config TS types with new error policy fields
These schema additions make errorPolicy/errorCooldownMs valid at runtime, but the exported Telegram config interfaces are not updated (src/config/types.telegram.ts still omits these properties on account/group/direct/topic configs). In TypeScript configs (for example openclaw.config.ts using satisfies OpenClawConfig), users will get "property does not exist" errors when using the new options, forcing unsafe casts and undermining the feature’s typed config workflow.
Useful? React with 👍 / 👎.
…sages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498
…-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes #34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
…chinar-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (openclaw#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
…chinar-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (openclaw#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
…chinar-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (openclaw#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
…chinar-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (openclaw#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
…chinar-amrutkar) * feat(telegram): add error policy for suppressing repetitive error messages Introduces per-account error policy configuration that can suppress repetitive error messages (e.g., 429 rate limit, ECONNRESET) to prevent noisy error floods in Telegram channels. Closes openclaw#34498 * fix(telegram): track error cooldown per message * fix(telegram): prune expired error cooldowns * fix: add Telegram error suppression controls (openclaw#51914) (thanks @chinar-amrutkar) --------- Co-authored-by: chinar-amrutkar <[email protected]> Co-authored-by: Ayaan Zaidi <[email protected]>
Summary
Change Type
Scope
Linked Issue/PR
User-visible / Behavior Changes
channels.telegram.errorPolicy(always/once/silent)channels.telegram.errorCooldownMs(default: 4 hours)channels.telegram.groups.<groupId>.errorPolicy(per-group override)Security Impact (required)
Repro + Verification
Environment
Steps
Expected
Actual
Evidence
Human Verification (required)
Compatibility / Migration
Failure Recovery (if this breaks)
Risks and Mitigations