{"record":{"id":"6351bd13244b18f9","repo":"nats-io/nats-server","slug":"pattern-requires-6-fields-got-d","errorCode":null,"errorMessage":"pattern requires 6 fields, got %d","messagePattern":"pattern requires 6 fields, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cron.go","lineNumber":52,"sourceCode":"// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\npackage server\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// parseCron parses the given cron pattern and returns the next time it will fire based on the provided ts.\nfunc parseCron(pattern string, loc *time.Location, ts int64) (time.Time, error) {\n\tfields := strings.Fields(pattern)\n\tif len(fields) != 6 {\n\t\treturn time.Time{}, fmt.Errorf(\"pattern requires 6 fields, got %d\", len(fields))\n\t}\n\n\t// If no time zone is passed, default to UTC.\n\tif loc == nil {\n\t\tloc = time.UTC\n\t}\n\n\t// Parse each field.\n\tvar err error\n\tvar second, minute, hour, dayOfMonth, month, dayOfWeek uint64\n\tif second, err = getField(fields[0], seconds); err != nil {\n\t\treturn time.Time{}, err\n\t}\n\tif minute, err = getField(fields[1], minutes); err != nil {\n\t\treturn time.Time{}, err\n\t}\n\tif hour, err = getField(fields[2], hours); err != nil {\n\t\treturn time.Time{}, err","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/cron.go#L34-L70","documentation":"parseCron validates that a cron pattern consists of exactly 6 whitespace-separated fields (sec min hour dom month dow). Patterns with fewer or more fields fail immediately before any field parsing. Message schedules (via parseMsgSchedule) funnel through this parser.","triggerScenarios":"Scheduling a message (e.g. schedule-based message delivery in JetStream) with a cron string like \"0 0 12 * *\" (5 fields) or \"0 0 12 * * * 2026\" (7 fields).","commonSituations":"Copy-pasting a standard 5-field crontab entry, which omits the seconds field that this parser requires; appending a year field that is unsupported.","solutions":["Add a seconds field so the pattern has exactly 6 fields: \"0 30 2 * * *\" (sec min hour dom mon dow)","Remove any extra fields such as year","Use the schedule format alternative if a cron expression is not required"],"exampleFix":"// before\n schedule := \"30 2 * * *\"\n// after\n schedule := \"0 30 2 * * *\"","handlingStrategy":"validation","validationCode":"func validateCron6(p string) error {\n    if n := len(strings.Fields(p)); n != 6 {\n        return fmt.Errorf(\"cron needs 6 fields, got %d\", n)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := parseCron(pattern, loc, time.Now().Unix()); err != nil {\n    log.Fatalf(\"invalid schedule %q: %v\", pattern, err)\n}","preventionTips":["Remember this parser requires seconds as the first field (6 fields total)","Test schedules with parseCron at startup, not at first use","Convert 5-field crontab entries by prefixing a seconds field"],"tags":["cron","parsing","scheduling"],"backgroundTag":"invalid-cron-expression","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}