{"record":{"id":"a1ff8c211b5ef508","repo":"gchq/CyberChef","slug":"invalid-base64-alphabet-length-alphabet-length","errorCode":null,"errorMessage":"Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}","messagePattern":"Invalid Base64 alphabet length \\((.+?)\\): (.+?)","errorType":"validation","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Base64.mjs","lineNumber":37,"sourceCode":" * @example\n * // returns \"SGVsbG8=\"\n * toBase64([72, 101, 108, 108, 111]);\n *\n * // returns \"SGVsbG8=\"\n * toBase64(\"Hello\");\n */\nexport function toBase64(data, alphabet=\"A-Za-z0-9+/=\") {\n    if (!data) return \"\";\n    if (typeof data == \"string\") {\n        data = Utils.strToArrayBuffer(data);\n    }\n    if (data instanceof ArrayBuffer) {\n        data = new Uint8Array(data);\n    }\n\n    alphabet = Utils.expandAlphRange(alphabet).join(\"\");\n    if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding\n        throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);\n    }\n\n    let output = \"\",\n        chr1, chr2, chr3,\n        enc1, enc2, enc3, enc4,\n        i = 0;\n\n    while (i < data.length) {\n        chr1 = data[i++];\n        chr2 = data[i++];\n        chr3 = data[i++];\n\n        enc1 = chr1 >> 2;\n        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n        enc4 = chr3 & 63;\n\n        if (isNaN(chr2)) {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Base64.mjs#L19-L55","documentation":"Thrown by toBase64() (Base64.mjs line 37) after Utils.expandAlphRange(alphabet).join('') when the resulting alphabet length is not 64 (or 65 with padding). expandAlphRange turns range shortcuts like 'A-Za-z0-9+/=' into the full character set; if the input is malformed or a different base's alphabet, the expanded length is wrong. Note toBase64 has NO fallback: an explicit '' alphabet expands to '' (length 0) and throws.","triggerScenarios":"Calling toBase64(data, 'A-Z0-9') (36 chars); passing a Base32/Base58/Base62 alphabet into the Base64 function; a typo like 'A-Za-z0-9+/' (63 chars, missing '='); an explicit empty-string alphabet.","commonSituations":"User supplies a custom alphabet in the 'To Base64' operation that is the wrong length; copying an alphabet from a different base operation; recipe using a custom alphabet that lost a character in transit.","solutions":["Use the default alphabet 'A-Za-z0-9+/=' (65 chars with padding) if you want standard Base64.","Provide exactly 64 distinct chars, or 65 if you include a padding char as the 65th.","If you need a different base, use the matching operation (To Base32/58/62/85), not Base64."],"exampleFix":"// before\ntoBase64(data, 'A-Z0-9'); // 36 chars\n\n// after\ntoBase64(data); // default standard alphabet\ntoBase64(data, 'A-Za-z0-9+/=');","handlingStrategy":"validation","validationCode":"import Utils from './core/Utils.mjs';\nfunction validB64Alphabet(a) {\n  const len = Utils.expandAlphRange(a).join('').length;\n  return len === 64 || len === 65;\n}\n// call before toBase64(data, alphabet)","typeGuard":"function isBase64Alphabet(a): boolean { const n = Utils.expandAlphRange(a).join('').length; return n === 64 || n === 65; }","tryCatchPattern":"try { toBase64(data, alphabet); } catch (e) {\n  if (e instanceof OperationError && /Invalid Base64 alphabet length/.test(e.message)) { alphabet = 'A-Za-z0-9+/='; }\n}","preventionTips":["Omit the alphabet argument to use the standard default.","Count chars: 64 for no padding, 65 with a padding char last.","Do not reuse Base32/58/62/85 alphabets for Base64."],"tags":["base64","encoding","alphabet","validation","operationerror"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}