{"record":{"id":"ba8bf30f59dda2bf","repo":"robfig/cron","slug":"expected-d-to-d-fields-found-d-s","errorCode":null,"errorMessage":"expected %d to %d fields, found %d: %s","messagePattern":"expected (.+?) to (.+?) fields, found (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"parser.go","lineNumber":189,"sourceCode":"\tif optionals > 1 {\n\t\treturn nil, fmt.Errorf(\"multiple optionals may not be configured\")\n\t}\n\n\t// Figure out how many fields we need\n\tmax := 0\n\tfor _, place := range places {\n\t\tif options&place > 0 {\n\t\t\tmax++\n\t\t}\n\t}\n\tmin := max - optionals\n\n\t// Validate number of fields\n\tif count := len(fields); count < min || count > max {\n\t\tif min == max {\n\t\t\treturn nil, fmt.Errorf(\"expected exactly %d fields, found %d: %s\", min, count, fields)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"expected %d to %d fields, found %d: %s\", min, max, count, fields)\n\t}\n\n\t// Populate the optional field if not provided\n\tif min < max && len(fields) == min {\n\t\tswitch {\n\t\tcase options&DowOptional > 0:\n\t\t\tfields = append(fields, defaults[5]) // TODO: improve access to default\n\t\tcase options&SecondOptional > 0:\n\t\t\tfields = append([]string{defaults[0]}, fields...)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown optional field\")\n\t\t}\n\t}\n\n\t// Populate all fields not part of options with their defaults\n\tn := 0\n\texpandedFields := make([]string, len(places))\n\tcopy(expandedFields, defaults)","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/robfig/cron/blob/bc59245fe10efaed9d51b56900192527ed733435/parser.go#L171-L207","documentation":"When the parser allows a range of field counts (an optional field is configured), the spec must contain between min and max fields. This error reports the acceptable range, the actual count, and the raw fields when the count falls outside it.","triggerScenarios":"Passing fewer than min fields (e.g. 4 fields to a Minute..Dow + DowOptional parser) or more than max fields (e.g. 7 fields with seconds optional).","commonSituations":"Malformed user-entered cron strings with missing or duplicated fields; specs containing stray tokens that split into extra fields; logging/audit expressions pasted with extra columns.","solutions":["Fix the spec to the correct number of fields shown in the error message","Trim extra whitespace/tokens and rebuild the spec from its components","Validate field count with strings.Fields before calling Parse"],"exampleFix":"// before\nsched, err := p.Parse(\"0 5 * * 1 extra\") // 6 fields to a max-6/optional parser... e.g. 7 tokens\n// after\nsched, err := p.Parse(\"0 5 * * 1\")","handlingStrategy":"validation","validationCode":"n := len(strings.Fields(spec))\nif n < 5 || n > 6 {\n\treturn fmt.Errorf(\"cron spec must have 5 or 6 fields, got %d\", n)\n}","typeGuard":null,"tryCatchPattern":"sched, err := parser.Parse(spec)\nif err != nil {\n\treturn fmt.Errorf(\"check field count in %q: %w\", spec, err)\n}","preventionTips":["Trim stray whitespace and tokens from user input","Validate field counts in an input form/API before parsing","Reject specs with more tokens than the maximum allowed fields"],"tags":["go","cron","parser","validation","field-count"],"backgroundTag":"invalid-argument-format","analyzedSha":"bc59245fe10efaed9d51b56900192527ed733435","analyzedAt":"2026-09-07T00:35:06.760Z","contentChangedAt":"2026-09-07T00:35:06.760Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}