gchq/CyberChef · error · OperationError

The all-zero group char cannot appear in the alphabet

Error message

The all-zero group char cannot appear in the alphabet

What it means

Thrown by From Base85 when the 'All-zero group char' (default 'z') is also a member of the alphabet. In Ascii85, the shorthand char represents a whole all-zero 4-byte group and must be distinct from every alphabet symbol; a collision would make decoding ambiguous. The check runs after the alphabet length/uniqueness validation.

Source

Thrown at src/core/operations/FromBase85.mjs:95

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {byteArray}
     */
    run(input, args) {
        const alphabet = Utils.expandAlphRange(args[0]).join(""),
            removeNonAlphChars = args[1],
            allZeroGroupChar = typeof args[2] === "string" ? args[2].slice(0, 1) : "",
            result = [];

        if (alphabet.length !== 85 ||
            [].unique.call(alphabet).length !== 85) {
            throw new OperationError("Alphabet must be of length 85");
        }

        if (allZeroGroupChar && alphabet.includes(allZeroGroupChar)) {
            throw new OperationError("The all-zero group char cannot appear in the alphabet");
        }

        // Remove delimiters if present
        const matches = input.match(/^<~(.+?)~>$/);
        if (matches !== null) input = matches[1];

        // Remove non-alphabet characters
        if (removeNonAlphChars) {
            const re = new RegExp("[^~" + allZeroGroupChar +alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
            input = input.replace(re, "");
            // Remove delimiters again if present (incase of non-alphabet characters in front/behind delimiters)
            const matches = input.match(/^<~(.+?)~>$/);
            if (matches !== null) input = matches[1];
        }

        if (input.length === 0) return [];

        let i = 0;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Change the 'All-zero group char' to a character not present in the alphabet.
  2. If the alphabet doesn't use 'z', keep the default; if it does, pick another char or empty it.
  3. Set the all-zero group char to empty to disable the shorthand entirely.

Example fix

// before: alphabet contains 'z' while shorthand is 'z'
fromBase85.run(input, ['A-Za-z0-9!.', true, 'z']) // 'z' in alphabet
// after: pick a non-colliding shorthand or disable it
fromBase85.run(input, ['A-Za-z0-9!.', true, ''])
Defensive patterns

Strategy: validation

Validate before calling

const alphabet = Utils.expandAlphRange(args[0]).join('');
const zeroChar = typeof args[2] === 'string' ? args[2].slice(0,1) : '';
if (zeroChar && alphabet.includes(zeroChar)) {
  // change zeroChar or clear it; do not call fromBase85.run()
}

Type guard

function zeroCharIsDistinct(zeroChar, alphabet) {
  return !zeroChar || !alphabet.includes(zeroChar);
}

Try / catch

try {
  fromBase85.run(input, args);
} catch (e) {
  if (e.type === 'OperationError' && /all-zero group char cannot appear/.test(e.message)) {
    // pick a non-colliding all-zero char or set it empty
  } else throw e;
}

Prevention

When it happens

Trigger: Using the default 'z' all-zero char with an alphabet that contains 'z' (e.g. a custom alphabet spanning lower-case letters); setting the all-zero char to a symbol that appears in the chosen alphabet; using the z85 alphabet which includes 'z' while keeping the default shorthand.

Common situations: Custom alphabet that inadvertently includes the shorthand char; switching alphabets without updating the all-zero group char; misunderstanding that 'z' shorthand is Ascii85-specific.

Related errors


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