{"record":{"id":"3912a7c0b5865734","repo":"gchq/CyberChef","slug":"incorrect-number-of-samples-check-your-input-and","errorCode":null,"errorMessage":"Incorrect number of samples. Check your input and/or delimiter.","messagePattern":"Incorrect number of samples\\. Check your input and/or delimiter\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/LevenshteinDistance.mjs","lineNumber":60,"sourceCode":"            },\n            {\n                name: \"Substitution cost\",\n                type: \"number\",\n                value: 1\n            },\n        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {number}\n     */\n    run(input, args) {\n        const [delim, insCost, delCost, subCost] = args;\n        const samples = input.split(delim);\n        if (samples.length !== 2) {\n            throw new OperationError(\"Incorrect number of samples. Check your input and/or delimiter.\");\n        }\n        if (insCost < 0 || delCost < 0 || subCost < 0) {\n            throw new OperationError(\"Negative costs are not allowed.\");\n        }\n        const src = samples[0], dest = samples[1];\n        let currentCost = new Array(src.length + 1);\n        let nextCost = new Array(src.length + 1);\n        for (let i = 0; i < currentCost.length; i++) {\n            currentCost[i] = delCost * i;\n        }\n        for (let i = 0; i < dest.length; i++) {\n            const destc = dest.charAt(i);\n            nextCost[0] = currentCost[0] + insCost;\n            for (let j = 0; j < src.length; j++) {\n                let candidate;\n                // insertion\n                let optCost = currentCost[j + 1] + insCost;\n                // deletion","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/LevenshteinDistance.mjs#L42-L78","documentation":"Thrown by the Levenshtein Distance operation when the input, split on the configured 'Sample delimiter' argument, does not produce exactly two samples. The operation compares exactly two strings, so it cannot proceed without a clear source and destination. The check is `samples.length !== 2` on line 59-61 of src/core/operations/LevenshteinDistance.mjs.","triggerScenarios":"Calling LevenshteinDistance.run(input, args) where `input.split(delim)` yields 0, 1, or 3+ parts. This happens when the input contains no delimiter occurrence, contains it more than once, or uses a different delimiter than the `delim` argument (default '\\n'). An empty input also yields length 1 and triggers this.","commonSituations":"Default delimiter is '\\n' but the user pasted two words separated by a space or comma on one line; a trailing newline produces a third empty sample; CRLF line endings split into an extra empty token when the delimiter is a single '\\n'; the delimiter argument was changed but the input was not updated to match.","solutions":["Ensure the input contains exactly one occurrence of the delimiter so it splits into precisely two samples (e.g. 'abc\\nabd').","Verify the 'Sample delimiter' argument matches the actual separator in your input; if input uses a comma, set the delimiter to ','.","Trim trailing newlines/whitespace from the input before running so no spurious empty third sample is produced.","If calling via the Node API, normalize the input to the form `src + delim + dest` before invoking run()."],"exampleFix":"// before: input = \"kitten\" (no delimiter), delim = \"\\n\"  -> throws\n// after:  input = \"kitten\\nsitting\", delim = \"\\n\"            -> returns 3","handlingStrategy":"validation","validationCode":"// Before calling LevenshteinDistance.run(input, [delim, insCost, delCost, subCost]):\nfunction validateLevenshteinInput(input, delim) {\n  if (typeof input !== \"string\" || typeof delim !== \"string\") {\n    throw new TypeError(\"input and delim must be strings\");\n  }\n  const parts = input.split(delim);\n  if (parts.length !== 2) {\n    throw new Error(`Expected exactly 2 samples separated by the delimiter, got ${parts.length}.`);\n  }\n  return parts; // [src, dest]\n}","typeGuard":"function isLevenshteinArgs(args) {\n  return Array.isArray(args)\n    && typeof args[0] === \"string\" // delim\n    && Number.isFinite(args[1]) && Number.isFinite(args[2]) && Number.isFinite(args[3]); // costs\n}","tryCatchPattern":"try {\n  const result = levenshtein.run(input, args);\n} catch (err) {\n  if (err instanceof OperationError && /Incorrect number of samples/.test(err.message)) {\n    // fix the input/delimiter, then retry with a corrected pair\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always construct the input as `src + delim + dest` so it contains exactly one delimiter.","Trim trailing newlines from pasted input to avoid a spurious empty third sample.","Keep the 'Sample delimiter' argument and the separator actually used in the input identical.","When feeding data from a file, normalize CRLF to LF if the delimiter is '\\n'."],"tags":["levenshtein","input-validation","delimiter","edit-distance","argument-mismatch"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}