From 44f2d29f1f00017c2b1048e3084c2bdd08bea712 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 12 May 2026 21:01:42 -0700 Subject: [PATCH 1/2] preserveUserFileBase64 is on and the event still exceeds the threshold, re-compact the event with preserveUserFileBase64: false --- apps/sim/lib/execution/event-buffer.ts | 31 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/apps/sim/lib/execution/event-buffer.ts b/apps/sim/lib/execution/event-buffer.ts index d04f9ea63cf..d459940c75a 100644 --- a/apps/sim/lib/execution/event-buffer.ts +++ b/apps/sim/lib/execution/event-buffer.ts @@ -293,15 +293,38 @@ async function compactEventForBuffer( return event } - const compactedData = await compactExecutionPayload(event.data, { + const baseOptions = { ...context, executionId: context.executionId ?? event.executionId, requireDurable: context.requireDurablePayloads, - preserveUserFileBase64: context.preserveUserFileBase64, preserveRoot: true, + } + + let compactedData = await compactExecutionPayload(event.data, { + ...baseOptions, + preserveUserFileBase64: context.preserveUserFileBase64, }) - const eventData = trimFinalBlockLogsForEventData(compactedData) - const eventDataSize = getJsonSize(eventData) + let eventData = trimFinalBlockLogsForEventData(compactedData) + let eventDataSize = getJsonSize(eventData) + + // SSE/replay events are size-bounded by LARGE_VALUE_THRESHOLD_BYTES. When a + // payload that preserved UserFile base64 (e.g., for chat/streaming) exceeds + // the cap, drop the inline base64 so consumers can lazily re-hydrate via + // sim.files.readBase64. This preserves the file metadata and keeps the + // event flowing instead of stalling the stream. + if ( + context.preserveUserFileBase64 && + eventDataSize !== null && + eventDataSize > LARGE_VALUE_THRESHOLD_BYTES + ) { + compactedData = await compactExecutionPayload(event.data, { + ...baseOptions, + preserveUserFileBase64: false, + }) + eventData = trimFinalBlockLogsForEventData(compactedData) + eventDataSize = getJsonSize(eventData) + } + if (eventDataSize !== null && eventDataSize > LARGE_VALUE_THRESHOLD_BYTES) { throw new Error( `Execution event data remains too large after compaction (${eventDataSize} bytes)` From f0d2431ba005a03447578c0b0f02b4247e87310a Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 12 May 2026 21:10:56 -0700 Subject: [PATCH 2/2] address comments --- apps/sim/lib/execution/event-buffer.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/sim/lib/execution/event-buffer.ts b/apps/sim/lib/execution/event-buffer.ts index d459940c75a..8c0d08090cb 100644 --- a/apps/sim/lib/execution/event-buffer.ts +++ b/apps/sim/lib/execution/event-buffer.ts @@ -309,20 +309,30 @@ async function compactEventForBuffer( // SSE/replay events are size-bounded by LARGE_VALUE_THRESHOLD_BYTES. When a // payload that preserved UserFile base64 (e.g., for chat/streaming) exceeds - // the cap, drop the inline base64 so consumers can lazily re-hydrate via - // sim.files.readBase64. This preserves the file metadata and keeps the - // event flowing instead of stalling the stream. + // the cap, recompact the already-compacted result with base64 stripped so + // consumers can lazily re-hydrate via sim.files.readBase64. Recompacting the + // *compacted* value (not the raw event.data) lets existing LargeValueRefs + // pass through unchanged and avoids minting fresh storage objects for the + // same large fields. if ( context.preserveUserFileBase64 && eventDataSize !== null && eventDataSize > LARGE_VALUE_THRESHOLD_BYTES ) { - compactedData = await compactExecutionPayload(event.data, { + const oversizedBytes = eventDataSize + compactedData = await compactExecutionPayload(compactedData, { ...baseOptions, preserveUserFileBase64: false, }) eventData = trimFinalBlockLogsForEventData(compactedData) eventDataSize = getJsonSize(eventData) + logger.warn('Stripped inline UserFile base64 from execution event to fit size limit', { + executionId: baseOptions.executionId, + eventType: 'type' in event ? event.type : undefined, + thresholdBytes: LARGE_VALUE_THRESHOLD_BYTES, + originalBytes: oversizedBytes, + strippedBytes: eventDataSize, + }) } if (eventDataSize !== null && eventDataSize > LARGE_VALUE_THRESHOLD_BYTES) {