@@ -293,15 +293,48 @@ async function compactEventForBuffer(
293293 return event
294294 }
295295
296- const compactedData = await compactExecutionPayload ( event . data , {
296+ const baseOptions = {
297297 ...context ,
298298 executionId : context . executionId ?? event . executionId ,
299299 requireDurable : context . requireDurablePayloads ,
300- preserveUserFileBase64 : context . preserveUserFileBase64 ,
301300 preserveRoot : true ,
301+ }
302+
303+ let compactedData = await compactExecutionPayload ( event . data , {
304+ ...baseOptions ,
305+ preserveUserFileBase64 : context . preserveUserFileBase64 ,
302306 } )
303- const eventData = trimFinalBlockLogsForEventData ( compactedData )
304- const eventDataSize = getJsonSize ( eventData )
307+ let eventData = trimFinalBlockLogsForEventData ( compactedData )
308+ let eventDataSize = getJsonSize ( eventData )
309+
310+ // SSE/replay events are size-bounded by LARGE_VALUE_THRESHOLD_BYTES. When a
311+ // payload that preserved UserFile base64 (e.g., for chat/streaming) exceeds
312+ // the cap, recompact the already-compacted result with base64 stripped so
313+ // consumers can lazily re-hydrate via sim.files.readBase64. Recompacting the
314+ // *compacted* value (not the raw event.data) lets existing LargeValueRefs
315+ // pass through unchanged and avoids minting fresh storage objects for the
316+ // same large fields.
317+ if (
318+ context . preserveUserFileBase64 &&
319+ eventDataSize !== null &&
320+ eventDataSize > LARGE_VALUE_THRESHOLD_BYTES
321+ ) {
322+ const oversizedBytes = eventDataSize
323+ compactedData = await compactExecutionPayload ( compactedData , {
324+ ...baseOptions ,
325+ preserveUserFileBase64 : false ,
326+ } )
327+ eventData = trimFinalBlockLogsForEventData ( compactedData )
328+ eventDataSize = getJsonSize ( eventData )
329+ logger . warn ( 'Stripped inline UserFile base64 from execution event to fit size limit' , {
330+ executionId : baseOptions . executionId ,
331+ eventType : 'type' in event ? event . type : undefined ,
332+ thresholdBytes : LARGE_VALUE_THRESHOLD_BYTES ,
333+ originalBytes : oversizedBytes ,
334+ strippedBytes : eventDataSize ,
335+ } )
336+ }
337+
305338 if ( eventDataSize !== null && eventDataSize > LARGE_VALUE_THRESHOLD_BYTES ) {
306339 throw new Error (
307340 `Execution event data remains too large after compaction (${ eventDataSize } bytes)`
0 commit comments