gchq/CyberChef · error · OperationError
Invalid Plaintext character : ${letter}
Error message
Invalid Plaintext character : ${letter} What it means
Thrown by the Lorenz SZ operation when, in plaintext Send mode (intype !== 'ITA2' and mode !== 'Receive'), an input character is not in the supported plaintext character set. Each character is upper-cased and looked up in validChars; a miss throws at Lorenz.mjs:519. The plaintext path then translates the character into ITA2, inserting figure/letter shifts as needed, so only characters it can encode are permitted.
Source
Thrown at src/core/operations/Lorenz.mjs:519
*/
convertToITA2(input, intype, mode) {
let result = "";
let figShifted = false;
for (const character of input) {
const letter = character.toUpperCase();
// Convert input text to ITA2 (including figure/letter shifts)
if (intype === "ITA2" || mode === "Receive") {
if (validITA2.indexOf(letter) === -1) {
let errltr = letter;
if (errltr==="\n") errltr = "Carriage Return";
if (errltr===" ") errltr = "Space";
throw new OperationError("Invalid ITA2 character : "+errltr);
}
result += letter;
} else {
if (validChars.indexOf(letter) === -1) throw new OperationError("Invalid Plaintext character : "+letter);
if (!figShifted && figShiftedChars.indexOf(letter) !== -1) {
// in letters mode and next char needs to be figure shifted
figShifted = true;
result += "55" + figShiftArr[letter];
} else if (figShifted) {
// in figures mode and next char needs to be letter shifted
if (letter==="\n") {
result += "34";
} else if (letter==="\r") {
result += "4";
} else if (figShiftedChars.indexOf(letter) === -1) {
figShifted = false;
result += "88" + letter;
} else {
result += figShiftArr[letter];
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Restrict input to the supported plaintext character set (basic A-Z, digits, and the punctuation symbols the operation encodes).
- Pre-sanitise input: strip or transliterate unsupported characters (e.g. smart quotes to ASCII, remove emoji) before running.
- If your data is already ITA2, switch 'Input Type' to 'ITA2' instead.
- Check the operation description / wiki for the exact plaintext alphabet supported.
Example fix
// before — unsupported Unicode in plaintext path input = '“HELLO” — café ☕'; // after — transliterate to supported plaintext input = '"HELLO" - cafe';
Defensive patterns
Strategy: validation
Validate before calling
// Approximate allow-list for the Lorenz plaintext path.
const VALID_PLAIN = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,?!:;\'"()-/+=&%#\n';
function onlyPlaintext(str) {
return [...str.toUpperCase()].every(c => VALID_PLAIN.includes(c));
}
if (intype !== 'ITA2' && mode !== 'Receive' && !onlyPlaintext(input)) {
throw new Error('Input has unsupported plaintext characters');
} Type guard
function isLorenzPlaintext(v: unknown): v is string {
if (typeof v !== 'string') return false;
const allowed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,?!:;\'"()-/+=&%#\n';
return [...v.toUpperCase()].every(c => allowed.includes(c));
} Prevention
- Transliterate smart quotes, accents, and emoji to ASCII before the plaintext path.
- If the data is already ITA2, switch Input Type to 'ITA2'.
- Sanitise pasted rich text to plain ASCII first.
When it happens
Trigger: Running the Lorenz operation with 'Input Type'='Plaintext' and 'Mode'='Send' (the default encoding direction) while the input contains a character the operation cannot represent in ITA2 — e.g. extended Unicode, emojis, accented letters, or punctuation not in the supported set. Raised at Lorenz.mjs:519.
Common situations: Pasting rich text / Unicode (curly quotes, accented characters, emoji) into the plaintext field; expecting arbitrary ASCII punctuation to be encodable; feeding binary/garbage data through the plaintext path.
Related errors
- Invalid ITA2 character : ${errltr}
- Χ1 custom lugs must be 41 long and can only include . or x
- Χ2 custom lugs must be 31 long and can only include . or x
- Χ3 custom lugs must be 29 long and can only include . or x
- Χ4 custom lugs must be 26 long and can only include . or x
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/b7ad8903633a7bdc.
Report an issue: GitHub.