gchq/CyberChef · error · OperationError
Error: all numbers must be between 1 and 26.
Error message
Error: all numbers must be between 1 and 26.
What it means
A1Z26 is a substitution cipher mapping 1→a, 2→b, … 26→z. The decoder splits the input string on a chosen delimiter and expects every resulting token to be an integer in the closed range [1, 26]. This OperationError is thrown inside the run loop when any token falls outside that range (note the comparison coerces the string token to a number, so an empty token becomes 0 and also trips the guard).
Source
Thrown at src/core/operations/A1Z26CipherDecode.mjs:86
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const delim = Utils.charRep(args[0] || "Space");
if (input.length === 0) {
return "";
}
const bites = input.split(delim);
let latin1 = "";
for (let i = 0; i < bites.length; i++) {
if (bites[i] < 1 || bites[i] > 26) {
throw new OperationError("Error: all numbers must be between 1 and 26.");
}
latin1 += Utils.chr(parseInt(bites[i], 10) + 96);
}
return latin1;
}
}
export default A1Z26CipherDecode;
View on GitHub (pinned to 4290ea7539)
Solutions
- Normalize the input: trim it and collapse repeated delimiters before running, e.g. input.trim().replace(/ +/g, ' ').
- Confirm the delimiter argument (args[0]) matches the one used when the text was encoded.
- Filter out empty tokens and any value outside 1–26 if you are preprocessing a noisy source.
- If the data legitimately contains numbers outside 1–26 or non-numeric symbols, A1Z26 is the wrong operation — use From Decimal or a custom parser instead.
Example fix
// before: input "1 2 27 " throws on 27 and trailing empty token
// after: pre-validate / sanitize
const clean = input.trim().split(/\s+/).filter(t => t !== '').join(' ');
// then run A1Z26CipherDecode on clean Defensive patterns
Strategy: validation
Validate before calling
function validateA1Z26Input(input, delim) {
const tokens = input.split(delim).filter(t => t.length > 0);
for (const t of tokens) {
const n = Number(t);
if (!Number.isInteger(n) || n < 1 || n > 26) {
throw new Error(`Token '${t}' is not an integer in [1,26]`);
}
}
return tokens.join(delim);
} Type guard
function isA1Z26Token(t) {
const n = Number(t);
return Number.isInteger(n) && n >= 1 && n <= 26;
} Try / catch
try {
runA1Z26(input, delim);
} catch (e) {
if (/between 1 and 26/.test(e.message)) {
// sanitize and retry, or surface to user
} else throw e;
} Prevention
- Trim and collapse repeated delimiters in the input before decoding.
- Confirm the decoder delimiter matches the encoder's delimiter.
- Pre-filter tokens to integers 1–26 when sourcing from noisy data.
When it happens
Trigger: Calling run() on input where any split token is < 1 or > 26. Concretely: a value of 0, 27, or a negative; an empty token produced by a leading/trailing/doubled delimiter (e.g. "1 2 " or "1 2" with Space delim yields ""); a non-numeric token that coerces to 0 (though non-numeric/NaN tokens actually slip past the range check and then break Utils.chr).
Common situations: Input pasted with a trailing space or double spaces; wrong delimiter selected (encoder used comma but decoder uses space); numbers exceeding 26 because the data is not actually A1Z26-encoded; mixing punctuation or whitespace into the token stream.
Related errors
- Invalid ciphertext length: ${originalLength} bytes. Must be
- No padding requested in ${mode} mode but input is not a 16-b
- With ECB or CBC modes, the input must be divisible into 16 b
- No padding requested but input length (${message.length} byt
- The key must consist only of letters in the English alphabet
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/7c92cc92ae019b65.
Report an issue: GitHub.