{"record":{"id":"63fc198315a34fa9","repo":"TheAlgorithms/JavaScript","slug":"duplicate-characters-in-character-set-are-not-allo","errorCode":null,"errorMessage":"Duplicate characters in character set are not allowed","messagePattern":"Duplicate characters in character set are not allowed","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Conversions/ArbitraryBase.js","lineNumber":39,"sourceCode":"const convertArbitraryBase = (\n  stringInBaseOne,\n  baseOneCharacterString,\n  baseTwoCharacterString\n) => {\n  if (\n    [stringInBaseOne, baseOneCharacterString, baseTwoCharacterString]\n      .map((arg) => typeof arg)\n      .some((type) => type !== 'string')\n  ) {\n    throw new TypeError('Only string arguments are allowed')\n  }\n\n  const baseOneCharacters = [...baseOneCharacterString]\n  const baseTwoCharacters = [...baseTwoCharacterString]\n\n  for (const charactersInBase of [baseOneCharacters, baseTwoCharacters]) {\n    if (charactersInBase.length !== new Set(charactersInBase).size) {\n      throw new TypeError(\n        'Duplicate characters in character set are not allowed'\n      )\n    }\n  }\n  const reversedStringOneChars = [...stringInBaseOne].reverse()\n  const stringOneBase = baseOneCharacters.length\n  let value = 0\n  let placeValue = 1\n  for (const digit of reversedStringOneChars) {\n    const digitNumber = baseOneCharacters.indexOf(digit)\n    if (digitNumber === -1) {\n      throw new TypeError(`Not a valid character: ${digit}`)\n    }\n    value += digitNumber * placeValue\n    placeValue *= stringOneBase\n  }\n  const outputChars = []\n  const stringTwoBase = baseTwoCharacters.length","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/Conversions/ArbitraryBase.js#L21-L57","documentation":"Thrown by convertArbitraryBase after the type guard passes, when either baseOneCharacterString or baseTwoCharacterString contains repeated characters. Uniqueness is required because each character maps bijectively to a digit value; a duplicate would make the value of a digit ambiguous and break both encoding and decoding. The check compares array length against a Set of the same characters.","triggerScenarios":"Calling convertArbitraryBase('10', '01', '0011') (output set '0011' has duplicate 0 and 1), or a source alphabet like '01234567890' with a repeated 0. Either character set triggering the duplicate is sufficient since the loop covers both arrays.","commonSituations":"Hand-typing a custom alphabet and accidentally repeating a glyph; reusing a charset constant that was concatenated incorrectly; using multibyte/emoji strings where a grapheme got duplicated; building a base alphabet from a range with an off-by-one overlap.","solutions":["Audit each character-set string and remove duplicates (e.g. [...set].join('')).","Generate alphabets programmatically from a known-unique source, e.g. '0123456789abcdef...', rather than typing them.","Add a pre-flight assertion in your caller: new Set(alpha).size === alpha.length."],"exampleFix":"// before\nconvertArbitraryBase('10', '01', '0011')\n// after\nconst dedupe = (s) => [...new Set([...s])].join('')\nconvertArbitraryBase('10', '01', dedupe('0011')) // -> '01'","handlingStrategy":"validation","validationCode":"const hasUniqueChars = (s) => [...s].length === new Set([...s]).size\nif (!hasUniqueChars(srcAlpha) || !hasUniqueChars(dstAlpha)) {\n  throw new Error('Character set must have unique glyphs')\n}\nconvertArbitraryBase(input, srcAlpha, dstAlpha)","typeGuard":"const isUniqueCharset = (s) =>\n  typeof s === 'string' && [...s].length === new Set([...s]).size","tryCatchPattern":"try {\n  convertArbitraryBase(input, srcAlpha, dstAlpha)\n} catch (e) {\n  if (/Duplicate characters/.test(e.message)) {\n    srcAlpha = [...new Set([...srcAlpha])].join('')\n    dstAlpha = [...new Set([...dstAlpha])].join('')\n    return convertArbitraryBase(input, srcAlpha, dstAlpha)\n  }\n  throw e\n}","preventionTips":["Generate alphabets from a known-unique source rather than hand-typing.","Add a Set-size assertion in tests for every charset constant.","Deduplicate at the boundary so the converter never sees duplicates."],"tags":["validation","base-conversion","unique-keys","charset","conversions"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}