Skip to content

Commit 08b3411

Browse files
ersinkocclaude
andcommitted
🐛 fix(ui): fix 'pairs.map is not a function' in HTTP Request workflow node
DB stores headers/queryParams as Record<string,string> but the config panel expected KeyValuePair[]. Added toKeyValuePairs() normalizer that handles both formats, and toRecord() converter for saving back to DB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ca29452 commit 08b3411

1 file changed

Lines changed: 32 additions & 6 deletions

File tree

packages/ui/src/components/workflows/panels/HttpRequestConfigPanel.tsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,32 @@ const BODY_TYPES: { value: BodyType; label: string }[] = [
7575
];
7676
const METHODS_WITH_BODY: HttpMethod[] = ['POST', 'PUT', 'PATCH'];
7777

78+
/**
79+
* Normalize headers/queryParams from DB format (Record<string,string>)
80+
* or UI format (KeyValuePair[]) into consistent KeyValuePair[].
81+
*/
82+
function toKeyValuePairs(input: unknown): KeyValuePair[] {
83+
if (Array.isArray(input)) return input as KeyValuePair[];
84+
if (input && typeof input === 'object' && !Array.isArray(input)) {
85+
return Object.entries(input as Record<string, string>).map(([key, value]) => ({
86+
key,
87+
value: String(value ?? ''),
88+
}));
89+
}
90+
return [];
91+
}
92+
93+
/**
94+
* Convert KeyValuePair[] back to Record<string,string> for DB storage.
95+
*/
96+
function toRecord(pairs: KeyValuePair[]): Record<string, string> {
97+
const result: Record<string, string> = {};
98+
for (const pair of pairs) {
99+
if (pair.key) result[pair.key] = pair.value;
100+
}
101+
return result;
102+
}
103+
78104
const METHOD_COLORS: Record<HttpMethod, string> = {
79105
GET: 'bg-blue-500/20 text-blue-600 dark:text-blue-400',
80106
POST: 'bg-green-500/20 text-green-600 dark:text-green-400',
@@ -170,8 +196,8 @@ export function HttpRequestConfigPanel({
170196
const [authUsername, setAuthUsername] = useState(data.authUsername ?? '');
171197
const [authPassword, setAuthPassword] = useState(data.authPassword ?? '');
172198
const [authHeaderName, setAuthHeaderName] = useState(data.authHeaderName ?? '');
173-
const [headers, setHeaders] = useState<KeyValuePair[]>(data.headers ?? []);
174-
const [queryParams, setQueryParams] = useState<KeyValuePair[]>(data.queryParams ?? []);
199+
const [headers, setHeaders] = useState<KeyValuePair[]>(toKeyValuePairs(data.headers));
200+
const [queryParams, setQueryParams] = useState<KeyValuePair[]>(toKeyValuePairs(data.queryParams));
175201
const [body, setBody] = useState(data.body ?? '');
176202
const [bodyType, setBodyType] = useState<BodyType>(data.bodyType ?? 'json');
177203
const [description, setDescription] = useState(data.description ?? '');
@@ -190,8 +216,8 @@ export function HttpRequestConfigPanel({
190216
setAuthUsername(data.authUsername ?? '');
191217
setAuthPassword(data.authPassword ?? '');
192218
setAuthHeaderName(data.authHeaderName ?? '');
193-
setHeaders(data.headers ?? []);
194-
setQueryParams(data.queryParams ?? []);
219+
setHeaders(toKeyValuePairs(data.headers));
220+
setQueryParams(toKeyValuePairs(data.queryParams));
195221
setBody(data.body ?? '');
196222
setBodyType(data.bodyType ?? 'json');
197223
setDescription(data.description ?? '');
@@ -532,7 +558,7 @@ export function HttpRequestConfigPanel({
532558
pairs={headers}
533559
onChange={(next) => {
534560
setHeaders(next);
535-
pushUpdate({ headers: next });
561+
pushUpdate({ headers: toRecord(next) as unknown as KeyValuePair[] });
536562
}}
537563
/>
538564

@@ -542,7 +568,7 @@ export function HttpRequestConfigPanel({
542568
pairs={queryParams}
543569
onChange={(next) => {
544570
setQueryParams(next);
545-
pushUpdate({ queryParams: next });
571+
pushUpdate({ queryParams: toRecord(next) as unknown as KeyValuePair[] });
546572
}}
547573
/>
548574

0 commit comments

Comments
 (0)