{"record":{"id":"3c1af98e0a92be0b","repo":"zloirock/core-js","slug":"invalidcharactererror","errorCode":"InvalidCharacterError","errorMessage":"The string is not correctly encoded","messagePattern":"The string is not correctly encoded","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"packages/core-js/modules/web.atob.js","lineNumber":61,"sourceCode":"\n// `atob` method\n// https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob\n$({ global: true, bind: true, enumerable: true, forced: FORCED }, {\n  atob: function atob(data) {\n    validateArgumentsLength(arguments.length, 1);\n    // `webpack` dev server bug on IE global methods - use call(fn, global, ...)\n    if (BASIC && !NO_SPACES_IGNORE && !NO_ENCODING_CHECK) return call($atob, globalThis, data);\n    var string = replace(toString(data), whitespaces, '');\n    var position = 0;\n    var bc = 0;\n    var length, chr, bs;\n    if (!(string.length & 3)) {\n      string = replace(string, finalEq, '');\n    }\n    length = string.length;\n    var lenmod = length & 3;\n    if (lenmod === 1 || exec(disallowed, string)) {\n      throw new (getBuiltIn('DOMException'))('The string is not correctly encoded', 'InvalidCharacterError');\n    }\n    // (length >> 2) is equivalent for length / 4 floored; * 3 then multiplies the\n    // number of bytes for full quanta\n    // lenmod is length % 4; if there's 2 or 3 bytes it's 1 or 2 bytes of extra output\n    // respectively, so -1, however use a ternary to ensure 0 does not get -1 onto length\n    var output = new $Array((length >> 2) * 3 + (lenmod ? lenmod - 1 : 0));\n    var outputIndex = 0;\n    while (position < length) {\n      chr = charAt(string, position++);\n      bs = bc & 3 ? (bs << 6) + c2i[chr] : c2i[chr];\n      if (bc++ & 3) output[outputIndex++] = fromCharCode(255 & bs >> (-2 * bc & 6));\n    }\n    return join(output, '');\n  }\n});\n","sourceCodeStart":43,"sourceCodeEnd":77,"githubUrl":"https://github.com/zloirock/core-js/blob/84e45fba098dd3a177d5cf2247d06ab8e98d3790/packages/core-js/modules/web.atob.js#L43-L77","documentation":"core-js's atob polyfill (packages/core-js/modules/web.atob.js:61) throws a DOMException 'InvalidCharacterError' when the input string is not valid base64: its length mod 4 is 1 after stripping trailing '=' padding, or it contains characters outside the base64 alphabet (whitespace is tolerated per spec). This mirrors the native window.atob behavior defined by the HTML Standard.","triggerScenarios":"Calling `atob(str)` where str has a leftover length of 1 modulo 4 (bad padding), or contains any character not in A-Z a-z 0-9 + / = (e.g. '-', '_', spaces inside the string, URL-safe base64, or a truncated/corrupted base64 value).","commonSituations":"Decoding JWT segments or tokens that were cut off in transit/storage; decoding base64url (base64 with '-' and '_') produced by other systems; strings that were HTML-escaped or contain newlines copied from logs; base64 produced without padding from a non-standard encoder.","solutions":["Verify the string is complete, correctly padded base64 (length % 4 === 0 after padding) and uses the standard alphabet (+ and /, not - and _).","If the source is base64url, convert it first: replace '-' with '+' and '_' with '/', then pad with '=' to a multiple of 4.","If the value is actually base64-encoded UTF-8 text, decode bytes with atob then decode with TextDecoder('utf-8') rather than expecting atob to return text.","Trim surrounding whitespace/newlines before calling atob (interior invalid characters still fail)."],"exampleFix":"// before\nconst json = JSON.parse(atob(token.split('.')[1]));\n// after\nlet b64 = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');\nwhile (b64.length % 4) b64 += '=';\nconst json = JSON.parse(atob(b64));","handlingStrategy":"validation","validationCode":"function isCanonicalBase64(s) {\n  return typeof s === 'string'\n    && /^[A-Za-z0-9+/]*={0,2}$/.test(s.trim())\n    && ((s.trim().length + 3) & ~3) % 4 === s.trim().length % 4 || /^[A-Za-z0-9+/]*={0,2}$/.test(s.trim());\n}\n// stricter: validate length mod 4 after stripping padding\nfunction isValidBase64(s) {\n  if (typeof s !== 'string') return false;\n  const t = s.trim().replace(/=+$/, '');\n  return /^[A-Za-z0-9+/]*$/.test(t) && t.length % 4 !== 1;\n}","typeGuard":"function isBase64String(v) {\n  return typeof v === 'string'\n    && /^[A-Za-z0-9+/]*={0,2}$/.test(v)\n    && (v.length % 4 === 0);\n}","tryCatchPattern":"let decoded;\ntry {\n  decoded = atob(input);\n} catch (e) {\n  if (e.name === 'InvalidCharacterError') {\n    throw new Error(`Malformed base64 input: ${input.slice(0, 20)}...`, { cause: e });\n  }\n  throw e;\n}","preventionTips":["Normalize base64url to standard base64 (replace -/_, re-pad) before atob.","Check length % 4 !== 1 and alphabet membership before decoding.","Never truncate base64 values when logging, storing, or splitting tokens.","Trim whitespace/newlines from copied values before decoding."],"tags":["atob","base64","invalid-character","encoding","polyfill"],"backgroundTag":"invalid-base64-encoding","analyzedSha":"84e45fba098dd3a177d5cf2247d06ab8e98d3790","analyzedAt":"2026-08-30T20:36:10.323Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}