{"record":{"id":"774f798d18e31637","repo":"gchq/CyberChef","slug":"take-every-must-be-a-positive-integer","errorCode":null,"errorMessage":"'Take every' must be a positive integer.","messagePattern":"'Take every' must be a positive integer\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/TakeNthBytes.mjs","lineNumber":57,"sourceCode":"                name: \"Apply to each line\",\n                type: \"boolean\",\n                value: false\n            }\n        ];\n    }\n\n    /**\n     * @param {byteArray} input\n     * @param {Object[]} args\n     * @returns {byteArray}\n     */\n    run(input, args) {\n        const n = args[0];\n        const start = args[1];\n        const eachLine = args[2];\n\n        if (parseInt(n, 10) !== n || n <= 0) {\n            throw new OperationError(\"'Take every' must be a positive integer.\");\n        }\n        if (parseInt(start, 10) !== start || start < 0) {\n            throw new OperationError(\"'Starting at' must be a positive or zero integer.\");\n        }\n\n        let offset = 0;\n        const output = [];\n        for (let i = 0; i < input.length; i++) {\n            if (eachLine && input[i] === 0x0a) {\n                output.push(0x0a);\n                offset = i + 1;\n            } else if (i - offset >= start && (i - (start + offset)) % n === 0) {\n                output.push(input[i]);\n            }\n        }\n\n        return output;\n    }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/TakeNthBytes.mjs#L39-L75","documentation":"Take Nth Bytes requires the 'Take every' argument (n) to be a positive integer. The guard `parseInt(n,10) !== n || n <= 0` rejects non-integers and values <= 0 before the sampling loop runs, because a non-positive or fractional stride is meaningless for byte selection.","triggerScenarios":"Passing a non-integer (e.g. 2.5) or a non-positive value (0, -1) for the 'Take every' argument. Also triggered by NaN or string values that fail the parseInt identity check.","commonSituations":"Leaving the field blank (defaults to an invalid value), entering 0 meaning 'take nothing', or pasting a decimal where an integer is expected.","solutions":["Enter a positive integer such as 1, 2, or 5 for 'Take every'.","Use 1 to keep every byte from the start offset onward.","Confirm no decimal point or negative sign is present in the field."],"exampleFix":"// before: args[0] (Take every) = 0   -> throws\n// after:  args[0] (Take every) = 2   -> keeps every 2nd byte","handlingStrategy":"type-guard","validationCode":"const n = args[0];\nif (!(Number.isInteger(n) && n > 0)) {\n  throw new Error(\"'Take every' must be a positive integer\");\n}","typeGuard":"const isPositiveInt = v => Number.isInteger(v) && v > 0;","tryCatchPattern":"try { takeNthBytes(input, n, start, eachLine); }\ncatch (e) { if (/Take every/.test(e.message)) { /* set n to a positive int */ } else throw e; }","preventionTips":["Validate stride with Number.isInteger before calling.","Default the field to 1 so it is always valid.","Reject fractional or negative input in your UI layer."],"tags":["validation","argument","integer","bytes"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}