Skip to content

Commit b981813

Browse files
fix: filter out error payloads from user-facing messages
isRenderablePayload did not check the isError flag, causing internal error results (context overflow, tool failures, role ordering conflicts) to leak to users on all messaging channels. These errors are meant to stay in the agent context for self-correction, not be delivered. Add tests for isRenderablePayload covering all payload types and the isError filtering behavior. Fixes #17828
1 parent a1e89af commit b981813

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { describe, expect, it } from "vitest";
2+
import { isRenderablePayload } from "./reply-payloads.js";
3+
4+
describe("isRenderablePayload", () => {
5+
it("returns true for payload with text", () => {
6+
expect(isRenderablePayload({ text: "hello" })).toBe(true);
7+
});
8+
9+
it("returns true for payload with mediaUrl", () => {
10+
expect(isRenderablePayload({ mediaUrl: "https://example.com/img.png" })).toBe(true);
11+
});
12+
13+
it("returns true for payload with mediaUrls", () => {
14+
expect(isRenderablePayload({ mediaUrls: ["https://example.com/a.png"] })).toBe(true);
15+
});
16+
17+
it("returns true for payload with audioAsVoice", () => {
18+
expect(isRenderablePayload({ audioAsVoice: true })).toBe(true);
19+
});
20+
21+
it("returns true for payload with channelData", () => {
22+
expect(isRenderablePayload({ channelData: { key: "value" } })).toBe(true);
23+
});
24+
25+
it("returns false for empty payload", () => {
26+
expect(isRenderablePayload({})).toBe(false);
27+
});
28+
29+
it("returns false for error payload even with text", () => {
30+
expect(isRenderablePayload({ text: "Context overflow error", isError: true })).toBe(false);
31+
});
32+
33+
it("returns false for error payload with media", () => {
34+
expect(isRenderablePayload({ mediaUrl: "https://example.com/img.png", isError: true })).toBe(
35+
false,
36+
);
37+
});
38+
39+
it("returns true for non-error payload with isError explicitly false", () => {
40+
expect(isRenderablePayload({ text: "hello", isError: false })).toBe(true);
41+
});
42+
});

src/auto-reply/reply/reply-payloads.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ export function applyReplyTagsToPayload(
4545
}
4646

4747
export function isRenderablePayload(payload: ReplyPayload): boolean {
48+
if (payload.isError) {
49+
return false;
50+
}
4851
return Boolean(
4952
payload.text ||
5053
payload.mediaUrl ||

0 commit comments

Comments
 (0)