From 6cdf69e0770142382e119c8e79aeb2fe4a34a62f Mon Sep 17 00:00:00 2001 From: soyelmismo Date: Sat, 30 May 2026 13:34:57 -0500 Subject: [PATCH] fix: address Kilo Code review feedback on PR #2951 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - estimateSizeFast: add WeakSet cycle detection to prevent infinite loop on circular object references - trace(): wrap JSON.stringify(extra) in try-catch to handle BigInt, circular refs, or other non-serializable values gracefully - Registry API change (Comment 3): verified all callers already use new getter functions — no broken call sites --- open-sse/handlers/chatCore.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/open-sse/handlers/chatCore.ts b/open-sse/handlers/chatCore.ts index b1eabdb92e..34c5aaf1b0 100644 --- a/open-sse/handlers/chatCore.ts +++ b/open-sse/handlers/chatCore.ts @@ -277,10 +277,11 @@ function cloneBoundedChatLogPayload(value: unknown, depth = 0): unknown { return result; } -/** Fast size estimator — walks object tree without JSON.stringify */ +/** Fast size estimator — walks object tree without JSON.stringify, with circular-ref protection */ function estimateSizeFast(value: unknown): number { let bytes = 0; const stack: unknown[] = [value]; + const seen = new WeakSet(); while (stack.length > 0) { const v = stack.pop(); if (v === null || v === undefined) continue; @@ -290,6 +291,8 @@ function estimateSizeFast(value: unknown): number { } else if (typeof v === "number") bytes += 8; else if (typeof v === "boolean") bytes += 4; else if (typeof v === "object") { + if (seen.has(v as object)) continue; + seen.add(v as object); if (Array.isArray(v)) { for (let i = 0; i < v.length; i++) stack.push(v[i]); } else { @@ -1544,7 +1547,14 @@ export async function handleChatCore({ const trace = (label: string, extra?: Record) => { if (!traceEnabled) return; const elapsed = Date.now() - startTime; - const suffix = extra ? ` ${JSON.stringify(extra)}` : ""; + let suffix = ""; + if (extra) { + try { + suffix = ` ${JSON.stringify(extra)}`; + } catch { + suffix = " [unserializable]"; + } + } log?.info?.("STAGE_TRACE", `${traceId} ${label} t=${elapsed}ms${suffix}`); }; let tokensCompressed: number | null = null;