{"record":{"id":"b827f581c91326b9","repo":"JamesNK/Newtonsoft.Json","slug":"step-cannot-be-zero","errorCode":null,"errorMessage":"Step cannot be zero.","messagePattern":"Step cannot be zero\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Linq/JsonPath/ArraySliceFilter.cs","lineNumber":18,"sourceCode":"using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing Newtonsoft.Json.Utilities;\n\nnamespace Newtonsoft.Json.Linq.JsonPath\n{\n    internal class ArraySliceFilter : PathFilter\n    {\n        public int? Start { get; set; }\n        public int? End { get; set; }\n        public int? Step { get; set; }\n\n        public override IEnumerable<JToken> ExecuteFilter(JToken root, IEnumerable<JToken> current, JsonSelectSettings? settings)\n        {\n            if (Step == 0)\n            {\n                throw new JsonException(\"Step cannot be zero.\");\n            }\n\n            foreach (JToken t in current)\n            {\n                if (t is JArray a)\n                {\n                    // set defaults for null arguments\n                    int stepCount = Step ?? 1;\n                    int startIndex = Start ?? ((stepCount > 0) ? 0 : a.Count - 1);\n                    int stopIndex = End ?? ((stepCount > 0) ? a.Count : -1);\n\n                    // start from the end of the list if start is negative\n                    if (Start < 0)\n                    {\n                        startIndex = a.Count + startIndex;\n                    }\n\n                    // end from the start of the list if stop is negative","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Linq/JsonPath/ArraySliceFilter.cs#L1-L36","documentation":"Thrown unconditionally by ArraySliceFilter.ExecuteFilter when the slice Step property equals zero. A slice step of zero would create an infinite loop, so the filter rejects it up front at ArraySliceFilter.cs:16-18 regardless of any ErrorWhenNoMatch setting. It originates from a JSONPath slice expression of the form [start:end:step] where step is 0.","triggerScenarios":"Using a JSONPath slice with an explicit zero step, e.g. token.SelectTokens(\"$.data[1:5:0]\"), which is parsed into ArraySliceFilter { Start=1, End=5, Step=0 }. The check fires before any token is examined, so it throws even on valid arrays.","commonSituations":"Building a slice expression dynamically where the step value is computed and can legitimately be zero; copying a Python-style slice but passing a zero stride; off-by-one in a computed step variable.","solutions":["Ensure the step portion of any slice expression is a non-zero integer (positive or negative).","If the step is computed dynamically, guard it: skip the slice or use step 1 when the computed step is 0.","Remove the explicit :0 from the slice and rely on the default step of 1."],"exampleFix":"// before\ntoken.SelectTokens($\"$.data[{start}:{end}:{step}]\");\n\n// after\nvar safeStep = step == 0 ? 1 : step;\ntoken.SelectTokens($\"$.data[{start}:{end}:{safeStep}]\");","handlingStrategy":"validation","validationCode":"// Never let step be zero in a slice expression\nint safeStep = (step == 0) ? 1 : step;\nstring path = $\"$.data[{start}:{end}:{safeStep}\";","typeGuard":null,"tryCatchPattern":"try\n{\n    token.SelectTokens($\"$.data[{start}:{end}:{step}]\");\n}\ncatch (JsonException ex) when (ex.Message.Contains(\"Step cannot be zero\"))\n{\n    // retry with default step of 1\n    token.SelectTokens($\"$.data[{start}:{end}:1]\");\n}","preventionTips":["Treat a computed step of zero as a no-op or substitute 1.","Validate any user-supplied slice parameters before embedding them in a path.","Unit-test slice generation against boundary inputs including step 0."],"tags":["jsonpath","array-slice","argument-validation"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}