gchq/CyberChef · error · OperationError

Invalid 'Diff by' option.

Error message

Invalid 'Diff by' option.

What it means

Thrown by Diff run() in the default branch of the diffBy switch, when the 'Diff by' option is not one of Character/Word/Line/Sentence/CSS/JSON. The args are constrained by an option list, so through the UI this is effectively unreachable; it only fires on programmatic invocation with an unlisted diffBy string or an imported recipe whose option value was renamed/removed.

Source

Thrown at src/core/operations/Diff.mjs:117

                break;
            case "Line":
                if (ignoreWhitespace) {
                    diff = jsdiff.diffTrimmedLines(samples[0], samples[1]);
                } else {
                    diff = jsdiff.diffLines(samples[0], samples[1]);
                }
                break;
            case "Sentence":
                diff = jsdiff.diffSentences(samples[0], samples[1]);
                break;
            case "CSS":
                diff = jsdiff.diffCss(samples[0], samples[1]);
                break;
            case "JSON":
                diff = jsdiff.diffJson(samples[0], samples[1]);
                break;
            default:
                throw new OperationError("Invalid 'Diff by' option.");
        }

        for (let i = 0; i < diff.length; i++) {
            if (diff[i].added) {
                if (showAdded) output += "<ins>" + Utils.escapeHtml(diff[i].value) + "</ins>";
            } else if (diff[i].removed) {
                if (showRemoved) output += "<del>" + Utils.escapeHtml(diff[i].value) + "</del>";
            } else if (!showSubtraction) {
                output += Utils.escapeHtml(diff[i].value);
            }
        }

        return output;
    }

}

export default Diff;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Use an exact value from the option list: 'Character', 'Word', 'Line', 'Sentence', 'CSS', or 'JSON' (case-sensitive).
  2. Regenerate or re-export the recipe in the current build.
  3. Validate diffBy against the allowed set before invoking run() programmatically.

Example fix

// before
op.run(input, [delim, "word", ...]); // wrong case

// after
op.run(input, [delim, "Word", ...]);
Defensive patterns

Strategy: validation

Validate before calling

const DIFF_BY = new Set(["Character", "Word", "Line", "Sentence", "CSS", "JSON"]);
function isValidDiffBy(v) { return DIFF_BY.has(v); }

Type guard

/** @returns {boolean} */
function isValidDiffBy(v) {
    return ["Character", "Word", "Line", "Sentence", "CSS", "JSON"].includes(v);
}

Try / catch

try {
    out = diff.run(input, args);
} catch (e) {
    if (e instanceof OperationError && /Invalid 'Diff by' option/.test(e.message)) {
        args[1] = "Line"; // safe default
        out = diff.run(input, args);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling run() with diffBy set to a string outside the supported set - e.g. 'Json' (wrong case), 'Lines' (plural), 'word' (lowercase), or a value from an older recipe format.

Common situations: Programmatic/Node-API call with a mistyped diff method; a recipe exported from a different version where the option label differs; a hand-built recipe file with an invalid diffBy enum.

Related errors


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