← Back to PRs

#3921: fix: sanitize fetch headers to prevent ByteString crash on Unicode (fixes #3897)

by nexiouscaliver open 2026-01-29 10:57 View on GitHub →
agents
This PR fixes a `ByteString` error (crash) in Node.js `undici` fetch when HTTP headers accidentally contain Unicode characters. This issue reportedly affects sending messages in Telegram and WhatsApp when the AI response contains Unicode characters (e.g. math symbols `≈`). Since Node.js 18+ (and specifically the `undici` implementation used in Node 22+) enforces strict Latin-1 checks on headers, passing Unicode in a header object causes a `TypeError` and crashes the gateway. Changes: - Added `sanitizeHeaders` utility in `src/infra/fetch.ts` to replace non-Latin1 characters (codepoints > 255) with `?`. - Updated `wrapFetchWithAbortSignal` to apply header sanitization automatically. - Added `installGlobalFetchSanitizer` to patch `globalThis.fetch` on startup. - Updated `src/entry.ts` to install the global fetch sanitizer, ensuring libraries like `Baileys` (WhatsApp) and `grammy` (Telegram) are protected even if they use the global fetch instance. This effectively shields the gateway from crashes caused by libraries or plugins inadvertently putting Unicode content (e.g. file names, metadata) into HTTP headers. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds a defensive header-sanitization layer around `fetch` to prevent undici’s strict ByteString (Latin-1) checks from throwing when header values contain Unicode. It introduces `sanitizeHeaders` in `src/infra/fetch.ts`, applies it in `wrapFetchWithAbortSignal`, and installs a global fetch wrapper early in `src/entry.ts` so third-party libraries using `globalThis.fetch` benefit as well. It also adds a small UX hook (`onCompactionStart`) to notify when auto-compaction begins, and hardens a workspace-paths test by avoiding plugin loading and restoring CWD reliably. Main concerns: the tuple-headers sanitization path can still throw if a library supplies a non-string header value (defeating the “shield from crashes” goal), and the new compaction notification uses `onPartialReply`, which may send a non-final message to external channels (Telegram/WhatsApp), contrary to the repo’s “no streaming/partial replies” guideline for those surfaces. <h3>Confidence Score: 3/5</h3> - Moderately safe to merge, but a couple of edge cases could reintroduce crashes or violate channel delivery expectations. - Core idea (sanitizing Unicode in header values) is sound and localized, but the tuple-header branch can throw on non-string values and the new compaction message uses a partial-reply hook that may reach external channels where non-final messages are disallowed. Fixing these would make the change low-risk. - src/infra/fetch.ts, src/auto-reply/reply/agent-runner-execution.ts <!-- 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> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs