Skip to content

Commit c723046

Browse files
authored
fix(logs): keep a block log's file size from changing after the block completes (#8626)
1 parent b2c5b76 commit c723046

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

‎apps/sim/executor/utils/output-filter.test.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,15 @@ describe('output filtering', () => {
4646
expect(output.nested).not.toHaveProperty('childTraceSpans')
4747
expect((output.nested as typeof nestedSpans).kept).toBe(nestedSpans.kept)
4848
})
49+
50+
it('keeps the file size a block completed with when hydration later updates it in place', () => {
51+
const file = { id: 'f1', key: 'k1', url: 'u', name: 'deck.pptx', size: 10, type: 'pptx' }
52+
const blockOutput = { file, rows: [{ id: 1 }] }
53+
54+
const output = filterOutputForLog('function', blockOutput as never)
55+
file.size = 4096
56+
57+
expect((output.file as typeof file).size).toBe(10)
58+
expect(output.rows).toBe(blockOutput.rows)
59+
})
4960
})

‎apps/sim/lib/logs/execution/trace-spans/trace-spans.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isUserFile } from '@/lib/core/utils/user-file'
12
import { groupIterationBlocks } from '@/lib/logs/execution/trace-spans/iteration-grouping'
23
import { createSpanFromLog } from '@/lib/logs/execution/trace-spans/span-factory'
34
import type { TraceSpan } from '@/lib/logs/types'
@@ -37,7 +38,7 @@ function setFilteredValue(output: Record<string, unknown>, key: string, value: u
3738
* returned as-is, so a block log shares structure with the block's compacted
3839
* state output instead of holding a second copy for the rest of the run. A
3940
* copy starts only at the first changed child; non-plain prototypes (Date,
40-
* class instances, null-prototype objects) are always rebuilt.
41+
* class instances, null-prototype objects) and file objects are always rebuilt.
4142
*/
4243
export function filterHiddenOutputKeys(value: unknown): unknown {
4344
if (value === null || value === undefined) {
@@ -63,8 +64,10 @@ export function filterHiddenOutputKeys(value: unknown): unknown {
6364

6465
if (typeof value === 'object') {
6566
const entries = Object.entries(value as Record<string, unknown>)
67+
// File objects are always copied: file hydration later updates `size` in
68+
// place on the shared state object, and a log keeps the value it completed with.
6669
let filtered: Record<string, unknown> | undefined =
67-
Object.getPrototypeOf(value) === Object.prototype ? undefined : {}
70+
Object.getPrototypeOf(value) === Object.prototype && !isUserFile(value) ? undefined : {}
6871
for (let index = 0; index < entries.length; index++) {
6972
const [key, val] = entries[index]
7073
const hidden = HIDDEN_OUTPUT_KEYS.has(key)

0 commit comments

Comments
 (0)