gchq/CyberChef · error · OperationError

Human-Readable Part (HRP) cannot be empty.

Error message

Human-Readable Part (HRP) cannot be empty.

What it means

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).

Source

Thrown at src/core/lib/Bech32.mjs:174

        }
    }

    return result;
}

/**
 * Encode data to Bech32/Bech32m string
 *
 * @param {string} hrp - Human-readable part
 * @param {number[]|Uint8Array} data - Data bytes to encode
 * @param {string} encoding - "Bech32" or "Bech32m"
 * @param {boolean} segwit - If true, treat first byte as witness version (for Bitcoin SegWit)
 * @returns {string} - Encoded Bech32/Bech32m string
 */
export function encode(hrp, data, encoding = "Bech32", segwit = false) {
    // Validate HRP
    if (!hrp || hrp.length === 0) {
        throw new OperationError("Human-Readable Part (HRP) cannot be empty.");
    }

    // Check HRP characters (ASCII 33-126)
    for (let i = 0; i < hrp.length; i++) {
        const c = hrp.charCodeAt(i);
        if (c < 33 || c > 126) {
            throw new OperationError(`HRP contains invalid character at position ${i}. Only printable ASCII characters (33-126) are allowed.`);
        }
    }

    // Convert HRP to lowercase
    const hrpLower = hrp.toLowerCase();

    let words;
    if (segwit && data.length >= 2) {
        // SegWit encoding: first byte is witness version (0-16), rest is witness program
        const witnessVersion = data[0];
        if (witnessVersion > 16) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide a non-empty HRP string, e.g. 'bc' for Bitcoin mainnet, 'tb' for testnet.
  2. Validate user/config input: if (!hrp) throw a clear error before calling encode.
  3. Set a sensible default HRP for your application context.
  4. Check that the variable holding the HRP is actually assigned.

Example fix

// before
const addr = encode(hrpFromConfigMaybeUndefined, program, 'Bech32', true);

// after
const HRP = hrpFromConfigMaybeUndefined || 'bc';
const addr = encode(HRP, program, 'Bech32', true);
Defensive patterns

Strategy: validation

Validate before calling

function requireHrp(hrp) {
  if (typeof hrp !== 'string' || hrp.length === 0) {
    throw new TypeError('A non-empty Bech32 HRP is required.');
  }
  return hrp;
}

Type guard

function isNonEmptyHrp(hrp) {
  return typeof hrp === 'string' && hrp.length > 0;
}

Try / catch

try {
  encode(hrp, data, 'Bech32', true);
} catch (e) {
  if (e instanceof OperationError && /HRP.*cannot be empty/.test(e.message)) {
    hrp = 'bc'; // fall back to a default HRP
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/6ce3e743103d71f7. Report an issue: GitHub.