{"record":{"id":"1ce0bb156779f72d","repo":"gchq/CyberChef","slug":"invalid-bech32-string-mixed-case-is-not-allowed","errorCode":null,"errorMessage":"Invalid Bech32 string: mixed case is not allowed. Use all uppercase or all lowercase.","messagePattern":"Invalid Bech32 string: mixed case is not allowed\\. Use all uppercase or all lowercase\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Bech32.mjs","lineNumber":251,"sourceCode":" * @param {string} encoding - \"Bech32\", \"Bech32m\", or \"Auto-detect\"\n * @returns {{hrp: string, data: number[]}} - Decoded HRP and data bytes\n */\nexport function decode(str, encoding = \"Auto-detect\") {\n    // Check for empty input\n    if (!str || str.length === 0) {\n        throw new OperationError(\"Input cannot be empty.\");\n    }\n\n    // Check maximum length\n    if (str.length > 90) {\n        throw new OperationError(`Invalid Bech32 string: exceeds maximum length of 90 characters (got ${str.length}).`);\n    }\n\n    // Check for mixed case\n    const hasUpper = /[A-Z]/.test(str);\n    const hasLower = /[a-z]/.test(str);\n    if (hasUpper && hasLower) {\n        throw new OperationError(\"Invalid Bech32 string: mixed case is not allowed. Use all uppercase or all lowercase.\");\n    }\n\n    // Convert to lowercase for processing\n    str = str.toLowerCase();\n\n    // Find separator (last occurrence of '1')\n    const sepIndex = str.lastIndexOf(\"1\");\n    if (sepIndex === -1) {\n        throw new OperationError(\"Invalid Bech32 string: no separator '1' found.\");\n    }\n\n    if (sepIndex === 0) {\n        throw new OperationError(\"Invalid Bech32 string: Human-Readable Part (HRP) cannot be empty.\");\n    }\n\n    if (sepIndex + 7 > str.length) {\n        throw new OperationError(\"Invalid Bech32 string: data part is too short (minimum 6 characters for checksum).\");\n    }","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Bech32.mjs#L233-L269","documentation":"Thrown by decode() in src/core/lib/Bech32.mjs:251 when the input contains both uppercase (A-Z) and lowercase (a-z) letters. BIP-0173 forbids mixed case: a Bech32 string must be entirely uppercase or entirely lowercase so that case-insensitive comparison is unambiguous. The check uses /[A-Z]/ and /[a-z]/ regexes; if both match, the string is invalid regardless of correctness.","triggerScenarios":"decode('bc1qABcDeFgH...') where some letters are upper and some lower. Happens when auto-correct or a title-case formatter touched the address, or when an uppercase address was partially lowercased.","commonSituations":"Mobile keyboards auto-capitalizing the first letter; copy-paste through a tool that title-cased the string; user manually edited part of the address; QR-code decoders that normalize case inconsistently.","solutions":["Normalize the whole string to one case before decoding: str.toLowerCase() or str.toUpperCase().","Disable auto-capitalization on input fields that accept addresses.","Validate case consistency before submitting and warn the user.","If normalizing changes the address, treat it as the canonical form (Bech32 case is not semantically significant)."],"exampleFix":"// before - mixed case\ndecode(userInput); // 'Bc1QAb...'\n\n// after - normalize to lowercase\ndecode(userInput.toLowerCase());","handlingStrategy":"validation","validationCode":"function normalizeBech32Case(str) {\n  const hasUpper = /[A-Z]/.test(str);\n  const hasLower = /[a-z]/.test(str);\n  if (hasUpper && hasLower) return str.toLowerCase(); // or toUpperCase\n  return str;\n}","typeGuard":"function isSingleCase(s) {\n  return typeof s === 'string' && !(/[A-Z]/.test(s) && /[a-z]/.test(s));\n}","tryCatchPattern":"try {\n  decode(input);\n} catch (e) {\n  if (e instanceof OperationError && /mixed case/.test(e.message)) {\n    input = input.toLowerCase(); // canonical fix\n  }\n}","preventionTips":["Normalize the whole address to one case before decoding.","Disable auto-capitalize on address input fields.","Warn users not to partially edit address case."],"tags":["bech32","decoding","bip-0173","case-sensitivity","input-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}