Skip to content

Commit bd2a30a

Browse files
fix(pii): fail fast on a null mask-batch body; use sleep() in gate test
A 200 response with a null JSON body threw TypeError on the data.masked read, which the retry classifier treats as transient — burning the full retry budget on a deterministic shape failure. Null-guard the body so it throws the non-retryable shape error immediately. Also swap the gate test's inline setTimeout promise for sleep() to satisfy check:utils, which failed CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1JYstmLHk9qMGyBDqYRcJ
1 parent e89845f commit bd2a30a

3 files changed

Lines changed: 14 additions & 3 deletions

File tree

apps/sim/lib/guardrails/mask-client.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ describe('maskPIIBatchViaHttp', () => {
109109
expect(mockToken).toHaveBeenCalledTimes(2)
110110
})
111111

112+
it('does not retry a null 200 body (deterministic, not a transient TypeError)', async () => {
113+
fetchMock.mockResolvedValueOnce(
114+
new Response('null', { status: 200, headers: { 'content-type': 'application/json' } })
115+
)
116+
117+
await expect(maskPIIBatchViaHttp(['a'], [])).rejects.toThrow(/unexpected result/)
118+
expect(fetchMock).toHaveBeenCalledTimes(1)
119+
expect(mockSleep).not.toHaveBeenCalled()
120+
})
121+
112122
it('does not retry a shape mismatch (deterministic server bug)', async () => {
113123
fetchMock.mockResolvedValueOnce(
114124
new Response(JSON.stringify({ nope: true }), {

apps/sim/lib/guardrails/mask-client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ async function postChunkOnce(
166166
)
167167
}
168168

169-
const data = (await response.json()) as GuardrailsMaskBatchResult
170-
if (!Array.isArray(data.masked)) {
169+
const data = (await response.json()) as GuardrailsMaskBatchResult | null
170+
if (!data || !Array.isArray(data.masked)) {
171171
throw new Error('PII mask-batch returned an unexpected result')
172172
}
173173
return data.masked

apps/sim/lib/logs/execution/pii-large-values.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @vitest-environment node
33
*/
4+
import { sleep } from '@sim/utils/helpers'
45
import { beforeEach, describe, expect, it, vi } from 'vitest'
56

67
const { mockMaterializeRef, mockStoreLargeValue, mockCompact, mockMaskBatch } = vi.hoisted(() => ({
@@ -244,7 +245,7 @@ describe('redactLargeValueRefs', () => {
244245
if (ref.size > 16 * 1024 * 1024) {
245246
inFlight++
246247
maxInFlight = Math.max(maxInFlight, inFlight)
247-
await new Promise((resolve) => setTimeout(resolve, 1))
248+
await sleep(1)
248249
inFlight--
249250
}
250251
return chunkData.get(ref.id)

0 commit comments

Comments
 (0)