{"record":{"id":"85035da8df359187","repo":"oven-sh/bun","slug":"generate-string-map-duplicate-key-json-stringif","errorCode":null,"errorMessage":"generate-string-map: duplicate key ${JSON.stringify(k)} in ${name}","messagePattern":"generate-string-map: duplicate key (.+?) in (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/codegen/generate-string-map.ts","lineNumber":223,"sourceCode":"      out.push(`            let mut probe = [0u8; ${len}];`);\n      out.push(`            for (d, s) in probe.iter_mut().zip(key) { *d = s.to_ascii_lowercase(); }`);\n      out.push(`            ${tableName}.binary_search_by(|(k, _)| k.cmp(&probe)).ok().map(|i| ${tableName}[i].1)`);\n      out.push(`        }`);\n    }\n  }\n  out.push(`        _ => None,`);\n  out.push(`    }`);\n  out.push(`}`);\n}\n\nfunction buildOne<V>(spec: StringMapSpec<V>): string {\n  const { name, valueTy, entries, emitKeys, emitIndexOf, emitCaseInsensitive, doc } = spec;\n  const emitValue = spec.emitValue ?? ((v: V) => (typeof v === \"string\" ? JSON.stringify(v) : String(v)));\n\n  const seen = new Set<string>();\n  const seenCi = new Set<string>();\n  for (const [k] of entries) {\n    if (seen.has(k)) throw new Error(`generate-string-map: duplicate key ${JSON.stringify(k)} in ${name}`);\n    seen.add(k);\n    if (emitCaseInsensitive) {\n      // eslint-disable-next-line no-control-regex\n      if (!/^[\\x00-\\x7f]*$/.test(k)) {\n        throw new Error(\n          `generate-string-map: ${name}: emitCaseInsensitive requires ASCII keys; ${JSON.stringify(k)} is not`,\n        );\n      }\n      const lk = k.toLowerCase();\n      if (seenCi.has(lk)) {\n        throw new Error(`generate-string-map: ${name}: keys ${JSON.stringify(k)} collide under case folding`);\n      }\n      seenCi.add(lk);\n    }\n  }\n\n  const kvs: Array<readonly [Buffer, string]> = entries.map(([k, v]) => [Buffer.from(k, \"utf8\"), emitValue(v)]);\n  const out: string[] = [];","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/codegen/generate-string-map.ts#L205-L241","documentation":"generate-string-map.ts compiles a TypeScript spec (e.g. src/js_parser/defines_table.string-map.ts) into Rust match-based string lookups. Every key in the spec's `entries` array must be unique, because the generated Rust code is a match over distinct byte literals; a second occurrence would produce dead arms. The error names the offending map (`name`) and the exact duplicated key.","triggerScenarios":"Running `bun src/codegen/generate-string-map.ts <input.string-map.ts> <out.rs>` where the input's `entries: [key, value][]` contains the same exact (case-sensitive) key string twice.","commonSituations":"Merging two entry lists into one map, copy-pasting an entry and changing only the value, or refactoring keys so two previously-distinct entries become identical.","solutions":["Remove or rename the duplicated key that the message prints (JSON.stringify shows it with quotes and escapes).","If both entries were intentional, merge their values or split them into two separate map specs.","Add a CI/lint step that dedupe-checks every *.string-map.ts before codegen runs."],"exampleFix":"// before\nexport default {\n  name: \"DefinesTable\",\n  entries: [\n    [\"BUN_1\", 1],\n    [\"BUN_1\", 2], // duplicate key\n  ],\n} satisfies StringMapSpec<number>;\n\n// after\nexport default {\n  name: \"DefinesTable\",\n  entries: [\n    [\"BUN_1\", 1],\n    [\"BUN_2\", 2],\n  ],\n} satisfies StringMapSpec<number>;","handlingStrategy":"validation","validationCode":"function assertUniqueKeys(name, entries) {\n  const seen = new Set();\n  for (const [k] of entries) {\n    if (seen.has(k)) throw new Error(`duplicate key ${JSON.stringify(k)} in ${name}`);\n    seen.add(k);\n  }\n}\n// run before: bun src/codegen/generate-string-map.ts input out.rs\nassertUniqueKeys(spec.name, spec.entries);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep entries alphabetically sorted so duplicates are visually obvious in review diffs.","Derive entries from a single source object (no duplicate object keys possible) instead of hand-written tuples.","Run the string-map generator as part of CI so bad specs fail the build, not a release."],"tags":["codegen","string-map","rust","build-time"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}