fix(telegram): safe DM threadless retry for missing message_thread_id#30892
Conversation
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🔵 Telegram API error-level logging suppressed on substring match, reducing monitoring visibility
DescriptionThe new This can weaken monitoring/alerting because:
Vulnerable/suppression logic: function isTelegramThreadNotFoundError(err: unknown): boolean {
if (err instanceof GrammyError) {
return THREAD_NOT_FOUND_RE.test(err.description);
}
return THREAD_NOT_FOUND_RE.test(formatErrorMessage(err));
}
const shouldSuppressFirstErrorLog = (err: unknown) =>
allowThreadlessRetry && hasThreadId && isTelegramThreadNotFoundError(err);
const mergedShouldLog = params.shouldLog
? (err: unknown) => params.shouldLog!(err) && !shouldSuppressFirstErrorLog(err)
: (err: unknown) => !shouldSuppressFirstErrorLog(err);Impact:
RecommendationTighten suppression to only apply to verified Telegram API thread-not-found errors, and still emit a high-signal event when suppression occurs. Suggested changes:
function isTelegramThreadNotFoundError(err: unknown): boolean {
return (
err instanceof GrammyError &&
err.error_code === 400 &&
/\bmessage thread not found\b/i.test(err.description)
);
}(Optionally also handle
params.runtime.error?.(
`telegram ${params.operation}: thread not found; will retry without message_thread_id`
);Or add a dedicated counter/telemetry hook.
Analyzed PR: #30892 at commit Last updated on: 2026-03-01T19:03:51Z |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 22b2eab156
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return await withTelegramApiErrorLogging({ | ||
| operation: `${params.operation} (threadless retry)`, | ||
| runtime: params.runtime, | ||
| fn: () => params.send(retryParams), |
There was a problem hiding this comment.
Preserve shouldLog filtering on threadless retry
Pass the caller's shouldLog predicate into the retry withTelegramApiErrorLogging call as well; otherwise DM-thread retries that hit handled errors on the second attempt (for example sendMessage parse/empty-text errors that fall back to plain text, or sendVoice VOICE_MESSAGES_FORBIDDEN that falls back to text) now emit danger logs even when delivery ultimately succeeds. This is a regression in log behavior introduced by the new retry path.
Useful? React with 👍 / 👎.
Greptile SummaryImplements DM-specific thread fallback for Telegram sends that fail with
Confidence Score: 4/5
Last reviewed commit: 22b2eab |
22b2eab to
3d77ab3
Compare
|
Landed via temp rebase onto main. Thanks @liuxiaopai-ai! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d77ab3b4b
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return await withTelegramApiErrorLogging({ | ||
| operation: `${params.operation} (threadless retry)`, | ||
| runtime: params.runtime, | ||
| fn: () => params.send(retryParams), |
There was a problem hiding this comment.
Pass shouldLog into threadless retry logger
The retry branch in sendTelegramWithThreadFallback calls withTelegramApiErrorLogging without forwarding params.shouldLog, so handled second-attempt errors now get danger-logged. Fresh evidence: sendTelegramText and sendVoice both pass filters (parse/empty text and VOICE_MESSAGES_FORBIDDEN) specifically so those fallback paths can succeed quietly, but after a DM message thread not found retry this omission causes noisy error logs even when delivery ultimately succeeds.
Useful? React with 👍 / 👎.
Summary
message thread not foundand break delivery; naive threadless fallback can also misroute forum-topic replies and trigger false danger logs on successful retry.message_thread_idonly forthread.scope === "dm", and suppresses first-attempt danger logging when that retry path is expected.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
message_thread_id.Security Impact (required)
No)No)No)No)No)Yes, explain risk + mitigation:Repro + Verification
Environment
dm/forum)Steps
pnpm exec vitest run src/telegram/bot/delivery.test.tspnpm buildExpected
message_thread_idand succeeds.Actual
Evidence
Commands run:
pnpm exec vitest run src/telegram/bot/delivery.test.tspnpm buildpnpm check(fails in this env due optional extension deps missing; unchanged baseline)Human Verification (required)
What you personally verified (not just CI), and how:
Compatibility / Migration
Yes)No)No)Failure Recovery (if this breaks)
src/telegram/bot/delivery.ts,src/telegram/bot/delivery.test.ts.Risks and Mitigations