← Back to PRs

#13467: fix(errors): prevent billing false positive in sanitizeUserFacingText

by lailoo open 2026-02-10 15:12 View on GitHub →
agents stale size: S trusted-contributor
## Summary Fixes #13434 ## Problem `sanitizeUserFacingText()` unconditionally applies `isBillingErrorMessage()` to all user-facing text. The `isBillingErrorMessage` function uses a broad heuristic that matches any text containing both "billing" and one of "payment", "upgrade", "credits", or "plan". This causes assistant-generated content discussing billing/payment topics (e.g., gym membership billing details) to be replaced with the generic billing error warning. ## Fix Add a `shouldRewriteBillingText()` guard function (matching the existing `shouldRewriteContextOverflowText()` pattern) that distinguishes real billing errors from assistant prose: 1. **Precise billing patterns** (`402`, `insufficient credits`, `credit balance`, `payment required`, `plans & billing`) are rewritten unconditionally — these are unambiguous error strings. 2. **Broad heuristic matches** (`billing + payment/upgrade/credits/plan`) are only rewritten when the text looks like a raw error message (API payload, HTTP error, error prefix, or single-sentence without markdown/paragraphs). ## Reproduction & Verification ### Unit-level (direct function call): **Before fix (main branch) — Bug reproduced:** ``` --- Assistant content (should NOT be rewritten) --- "**Billing:** Processed through ABC Financial Services..." ❌ FALSE POSITIVE "The gym membership billing cycle runs monthly..." ❌ FALSE POSITIVE "Here is a summary of the billing and payment options..." ❌ FALSE POSITIVE ``` **After fix — All verified:** ``` --- Assistant content (should NOT be rewritten) --- ✅ PASS (all assistant content samples preserved) --- Real billing errors (SHOULD be rewritten) --- ✅ PASS: "insufficient credits" ✅ PASS: "billing: please upgrade your plan" ✅ PASS: "Your credit balance is too low" ``` ### Integration-level (real gateway reply pipeline): Added `normalizeReplyPayload` integration tests in `src/auto-reply/reply/normalize-reply.test.ts` that exercise the full reply normalization pipeline (`normalizeReplyPayload` → `sanitizeUserFacingText`): **Before fix (main branch) — Bug reproduced through real pipeline:** ``` normalizeReplyPayload({ text: "**Billing:** ... payments ..." }) → text: "⚠️ API provider returned a billing error..." ❌ FALSE POSITIVE ``` **After fix — Pipeline preserves assistant content:** ``` normalizeReplyPayload({ text: "**Billing:** ... payments ..." }) → text: "**Billing:** Processed through ABC Financial Services..." ✅ PRESERVED normalizeReplyPayload({ text: "insufficient credits" }) → text: "⚠️ API provider returned a billing error..." ✅ REWRITTEN ``` ## Effect on User Experience **Before fix:** Sub-agent researches gym membership details → output contains "Billing: ... payments" → parent receives "⚠️ API provider returned a billing error" instead of actual findings. **After fix:** Assistant content discussing billing/payment topics is delivered as-is. Real billing errors (402, insufficient credits, etc.) are still correctly caught and rewritten. ## Testing - ✅ 14 unit tests pass (12 existing + 2 new regression tests in `sanitizeuserfacingtext.test.ts`) - ✅ 2 new integration tests pass (`normalizeReplyPayload` pipeline in `normalize-reply.test.ts`) - ✅ `isBillingErrorMessage()` unchanged — error classification for failover/logging still works

Most Similar PRs