Skip to content

Commit 78c3b4e

Browse files
committed
fix(supabase): edge-function error handling + reject array headers
- invoke_function: drop unreachable !response.ok branch (executor throws on non-OK before transformResponse runs and surfaces the error body); document the success-only contract - invoke_function: ignore non-object (array) headers so JSON arrays can't produce numeric-index header names - block: reject array/non-object Edge Function headers with a clear error in config.params
1 parent bb72c7c commit 78c3b4e

2 files changed

Lines changed: 17 additions & 16 deletions

File tree

apps/sim/blocks/blocks/supabase.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,17 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
11221122
parsedFunctionHeaders = functionHeaders
11231123
}
11241124

1125+
if (
1126+
parsedFunctionHeaders !== undefined &&
1127+
(typeof parsedFunctionHeaders !== 'object' ||
1128+
parsedFunctionHeaders === null ||
1129+
Array.isArray(parsedFunctionHeaders))
1130+
) {
1131+
throw new Error(
1132+
'Edge Function headers must be a JSON object of header name to value (not an array).'
1133+
)
1134+
}
1135+
11251136
let parsedAllowedMimeTypes
11261137
if (allowedMimeTypes && typeof allowedMimeTypes === 'string' && allowedMimeTypes.trim()) {
11271138
try {

apps/sim/tools/supabase/invoke_function.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const invokeFunctionTool: ToolConfig<
8787
Authorization: `Bearer ${params.apiKey}`,
8888
'Content-Type': 'application/json',
8989
}
90-
if (params.headers && typeof params.headers === 'object') {
90+
if (params.headers && typeof params.headers === 'object' && !Array.isArray(params.headers)) {
9191
for (const [key, value] of Object.entries(params.headers)) {
9292
headers[key] = String(value)
9393
}
@@ -102,6 +102,11 @@ export const invokeFunctionTool: ToolConfig<
102102
},
103103
},
104104

105+
/**
106+
* Only the success path is handled here — the tool executor throws on
107+
* non-OK responses before `transformResponse` runs, surfacing the Edge
108+
* Function's error body via the shared error extractor.
109+
*/
105110
transformResponse: async (response: Response) => {
106111
const contentType = response.headers.get('content-type') || ''
107112
let results: unknown
@@ -115,21 +120,6 @@ export const invokeFunctionTool: ToolConfig<
115120
results = await response.text()
116121
}
117122

118-
if (!response.ok) {
119-
const message =
120-
typeof results === 'object' && results !== null && 'error' in results
121-
? String((results as { error: unknown }).error)
122-
: `Edge Function returned status ${response.status}`
123-
return {
124-
success: false,
125-
output: {
126-
message,
127-
results,
128-
},
129-
error: message,
130-
}
131-
}
132-
133123
return {
134124
success: true,
135125
output: {

0 commit comments

Comments
 (0)