{"record":{"id":"f3700f6ed269b0b6","repo":"FlowiseAI/Flowise","slug":"invalid-header-key-must-be-a-non-empty-string","errorCode":null,"errorMessage":"Invalid header: key must be a non-empty string","messagePattern":"Invalid header: key must be a non-empty string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/headerValidation.ts","lineNumber":51,"sourceCode":"/**\n * Validates a set of user-supplied HTTP headers intended for outbound requests.\n * Rejects malformed keys, CRLF/control-char injection in values, hop-by-hop and\n * sensitive header names, and oversized payloads. Throws a plain Error; callers\n * are responsible for mapping to their own error types.\n */\nexport function validateCustomHeaders(headers: Record<string, string>): void {\n    if (!headers || typeof headers !== 'object') {\n        throw new Error('Invalid headers: expected an object')\n    }\n\n    const entries = Object.entries(headers)\n    if (entries.length > MAX_HEADERS) {\n        throw new Error(`Invalid headers: too many entries (max ${MAX_HEADERS})`)\n    }\n\n    for (const [key, value] of entries) {\n        if (typeof key !== 'string' || key.length === 0) {\n            throw new Error('Invalid header: key must be a non-empty string')\n        }\n        if (key.length > MAX_KEY_LENGTH) {\n            throw new Error(`Invalid header \"${key}\": key exceeds ${MAX_KEY_LENGTH} chars`)\n        }\n        if (!RFC7230_TOKEN.test(key)) {\n            throw new Error(`Invalid header \"${key}\": key contains illegal characters`)\n        }\n\n        const lower = key.toLowerCase()\n        if (DENIED_HEADER_NAMES.has(lower) || DENIED_HEADER_PREFIXES.some((p) => lower.startsWith(p))) {\n            throw new Error(`Invalid header \"${key}\": this header name is not allowed`)\n        }\n\n        if (typeof value !== 'string') {\n            throw new Error(`Invalid header \"${key}\": value must be a string`)\n        }\n        if (value.length > MAX_VALUE_LENGTH) {\n            throw new Error(`Invalid header \"${key}\": value exceeds ${MAX_VALUE_LENGTH} chars`)","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/headerValidation.ts#L33-L69","documentation":"Per-entry guard: each key must be a non-empty string. Plain-object keys are always strings, so this primarily catches empty-string keys ({\"\": \"v\"}) or numeric/array-like keys that slip through when an array is passed (Object.entries on an array yields ['0', value]).","triggerScenarios":"Header bag contains an empty-string key, or an array is passed whose entries have numeric-string keys (key '0' survives non-empty but later fails RFC7230_TOKEN), or a Map/object with non-string keys was used upstream.","commonSituations":"Caller passed an array of values instead of an object; empty header name from user input not filtered; key/value swap left the name blank.","solutions":["Pass a plain object keyed by valid header names (no empty keys).","Filter out empty-key entries before calling: `Object.fromEntries(Object.entries(h).filter(([k]) => k !== ''))`.","If you have an array of values, map them to {key: value} pairs explicitly."],"exampleFix":"// before\nvalidateCustomHeaders({ '': 'no-name' }) // throws\nvalidateCustomHeaders(['a','b']) // array, key '0' passes here but fails later\n\n// after\nvalidateCustomHeaders({ 'X-Trace-Id': 'a' })","handlingStrategy":"validation","validationCode":"// Strip empty-key entries before validation\nfunction dropEmptyKeys(headers) {\n    return Object.fromEntries(Object.entries(headers).filter(([k]) => typeof k === 'string' && k.length > 0))\n}","typeGuard":"function hasNoEmptyKeys(headers) {\n    return Object.keys(headers).every((k) => typeof k === 'string' && k.length > 0)\n}","tryCatchPattern":"try {\n    validateCustomHeaders(headers)\n} catch (e) {\n    if (/key must be a non-empty string/i.test(e.message)) headers = dropEmptyKeys(headers)\n    else throw e\n    validateCustomHeaders(headers)\n}","preventionTips":["Pass a plain object, never an array.","Filter empty header names from user input at the form boundary.","Catch key/value swaps at the UI (the field labeled 'name' should hold a name)."],"tags":["headers","validation","http"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}