{"record":{"id":"403735e50b64547e","repo":"decolua/9router","slug":"aws-eventstream-contains-duplicate-header-name","errorCode":null,"errorMessage":"AWS EventStream contains duplicate header: ${name}","messagePattern":"AWS EventStream contains duplicate header: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"open-sse/executors/kiro.js","lineNumber":1234,"sourceCode":"  }\n\n  const headers = Object.create(null);\n  const names = new Set();\n  let offset = 12;\n  const headerEnd = offset + headersLength;\n  const requireBytes = (count) => {\n    if (offset + count > headerEnd) {\n      throw new Error(\"AWS EventStream header exceeds its declared bounds\");\n    }\n  };\n\n  while (offset < headerEnd) {\n    requireBytes(1);\n    const nameLength = data[offset++];\n    requireBytes(nameLength + 1);\n    const name = decoder.decode(data.subarray(offset, offset + nameLength));\n    offset += nameLength;\n    if (names.has(name)) throw new Error(`AWS EventStream contains duplicate header: ${name}`);\n    names.add(name);\n    const type = data[offset++];\n\n    if (type === 0 || type === 1) {\n      headers[name] = type === 0;\n    } else if (type === 2) {\n      requireBytes(1);\n      headers[name] = view.getInt8(offset);\n      offset += 1;\n    } else if (type === 3) {\n      requireBytes(2);\n      headers[name] = view.getInt16(offset, false);\n      offset += 2;\n    } else if (type === 4) {\n      requireBytes(4);\n      headers[name] = view.getInt32(offset, false);\n      offset += 4;\n    } else if (type === 5 || type === 8) {","sourceCodeStart":1216,"sourceCodeEnd":1252,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/executors/kiro.js#L1216-L1252","documentation":"While decoding an AWS EventStream frame's header section, parseEventFrame() tracks every header name it has seen in a Set. AWS EventStream headers are a map, so a repeated name means the frame violates the protocol and its content is ambiguous; the parser throws immediately instead of silently letting a later value overwrite an earlier one.","triggerScenarios":"The bytes of a frame's header section decode to two entries with the same header name. Produced by corrupted/truncated binary data, a frame re-assembled from the wrong byte offsets, or an upstream bug emitting duplicated headers.","commonSituations":"Middlebox/proxy mangling the binary Kiro stream; protocol drift after a Kiro upstream update; reading frames with a stale parser version after the wire format gained new header entries.","solutions":["Update 9router to the latest version to pick up any parser fixes for the current Kiro wire format","Bypass or remove intermediaries (proxies, logging middlewares) that may corrupt the binary stream","Retry the request — a single corrupted frame in a long stream is usually transient","Log the offending frame (hex/base64) and verify the header section against the AWS EventStream spec to confirm upstream duplication","If reproducible per-account, re-authenticate or switch accounts in case a specific backend node is emitting bad frames"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await executor.execute(req);\n} catch (e) {\n  if (String(e.message).includes('duplicate header')) {\n    return retryOrFallback(req, 'eventstream-duplicate-header');\n  }\n  throw e;\n}","preventionTips":["Keep the parser and 9router version current with Kiro's protocol","Bypass middleboxes that could duplicate/reassemble frame bytes","Treat any EventStream parse error as corrupt-input and retry, not as a client bug"],"tags":["kiro","eventstream","binary-protocol","protocol-violation"],"backgroundTag":"eventstream-frame-malformed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}