{"record":{"id":"6ce3e743103d71f7","repo":"gchq/CyberChef","slug":"human-readable-part-hrp-cannot-be-empty","errorCode":null,"errorMessage":"Human-Readable Part (HRP) cannot be empty.","messagePattern":"Human-Readable Part \\(HRP\\) cannot be empty\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Bech32.mjs","lineNumber":174,"sourceCode":"        }\n    }\n\n    return result;\n}\n\n/**\n * Encode data to Bech32/Bech32m string\n *\n * @param {string} hrp - Human-readable part\n * @param {number[]|Uint8Array} data - Data bytes to encode\n * @param {string} encoding - \"Bech32\" or \"Bech32m\"\n * @param {boolean} segwit - If true, treat first byte as witness version (for Bitcoin SegWit)\n * @returns {string} - Encoded Bech32/Bech32m string\n */\nexport function encode(hrp, data, encoding = \"Bech32\", segwit = false) {\n    // Validate HRP\n    if (!hrp || hrp.length === 0) {\n        throw new OperationError(\"Human-Readable Part (HRP) cannot be empty.\");\n    }\n\n    // Check HRP characters (ASCII 33-126)\n    for (let i = 0; i < hrp.length; i++) {\n        const c = hrp.charCodeAt(i);\n        if (c < 33 || c > 126) {\n            throw new OperationError(`HRP contains invalid character at position ${i}. Only printable ASCII characters (33-126) are allowed.`);\n        }\n    }\n\n    // Convert HRP to lowercase\n    const hrpLower = hrp.toLowerCase();\n\n    let words;\n    if (segwit && data.length >= 2) {\n        // SegWit encoding: first byte is witness version (0-16), rest is witness program\n        const witnessVersion = data[0];\n        if (witnessVersion > 16) {","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Bech32.mjs#L156-L192","documentation":"Thrown by encode() in src/core/lib/Bech32.mjs:174 when the Human-Readable Part (HRP) argument is falsy or an empty string. The HRP — the prefix before the '1' separator, like 'bc' for Bitcoin mainnet — is mandatory in Bech32; without it the checksum cannot be computed because the HRP participates in the polymod (hrpExpand).","triggerScenarios":"encode('', data), encode(null, data), encode(undefined, data). Any caller that derives the HRP from config/user input and passes it through without a presence check.","commonSituations":"Config typo where the HRP key is misspelled or missing; a UI form where the HRP field was left blank; defaulting HRP to undefined when it should be 'bc'/'tb'/'bcrt'; refactoring that dropped the HRP argument.","solutions":["Provide a non-empty HRP string, e.g. 'bc' for Bitcoin mainnet, 'tb' for testnet.","Validate user/config input: if (!hrp) throw a clear error before calling encode.","Set a sensible default HRP for your application context.","Check that the variable holding the HRP is actually assigned."],"exampleFix":"// before\nconst addr = encode(hrpFromConfigMaybeUndefined, program, 'Bech32', true);\n\n// after\nconst HRP = hrpFromConfigMaybeUndefined || 'bc';\nconst addr = encode(HRP, program, 'Bech32', true);","handlingStrategy":"validation","validationCode":"function requireHrp(hrp) {\n  if (typeof hrp !== 'string' || hrp.length === 0) {\n    throw new TypeError('A non-empty Bech32 HRP is required.');\n  }\n  return hrp;\n}","typeGuard":"function isNonEmptyHrp(hrp) {\n  return typeof hrp === 'string' && hrp.length > 0;\n}","tryCatchPattern":"try {\n  encode(hrp, data, 'Bech32', true);\n} catch (e) {\n  if (e instanceof OperationError && /HRP.*cannot be empty/.test(e.message)) {\n    hrp = 'bc'; // fall back to a default HRP\n  }\n}","preventionTips":["Always pass an explicit, known HRP constant.","Validate config/user input for the HRP before encoding.","Centralize HRP selection in one module to avoid passing undefined around."],"tags":["bech32","encoding","hrp","input-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}