{"record":{"id":"7e3da09588fd574c","repo":"robfig/cron","slug":"parser-does-not-accept-descriptors-v","errorCode":null,"errorMessage":"parser does not accept descriptors: %v","messagePattern":"parser does not accept descriptors: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"parser.go","lineNumber":108,"sourceCode":"\t\treturn nil, fmt.Errorf(\"empty spec string\")\n\t}\n\n\t// Extract timezone if present\n\tvar loc = time.Local\n\tif strings.HasPrefix(spec, \"TZ=\") || strings.HasPrefix(spec, \"CRON_TZ=\") {\n\t\tvar err error\n\t\ti := strings.Index(spec, \" \")\n\t\teq := strings.Index(spec, \"=\")\n\t\tif loc, err = time.LoadLocation(spec[eq+1 : i]); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"provided bad location %s: %v\", spec[eq+1:i], err)\n\t\t}\n\t\tspec = strings.TrimSpace(spec[i:])\n\t}\n\n\t// Handle named schedules (descriptors), if configured\n\tif strings.HasPrefix(spec, \"@\") {\n\t\tif p.options&Descriptor == 0 {\n\t\t\treturn nil, fmt.Errorf(\"parser does not accept descriptors: %v\", spec)\n\t\t}\n\t\treturn parseDescriptor(spec, loc)\n\t}\n\n\t// Split on whitespace.\n\tfields := strings.Fields(spec)\n\n\t// Validate & fill in any omitted or optional fields\n\tvar err error\n\tfields, err = normalizeFields(fields, p.options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfield := func(field string, r bounds) uint64 {\n\t\tif err != nil {\n\t\t\treturn 0\n\t\t}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/robfig/cron/blob/bc59245fe10efaed9d51b56900192527ed733435/parser.go#L90-L126","documentation":"Parse treats specs starting with '@' as named descriptors (@yearly, @hourly, etc.), but only if the Descriptor option was passed to NewParser. Without that bit, any '@'-prefixed spec is rejected with this error naming the offending spec.","triggerScenarios":"Calling Parse(\"@daily\") or Parse(\"@every 1h\") on a Parser created without the Descriptor option bit, e.g. NewParser(Minute|Hour|Dom|Month|Dow).","commonSituations":"Using cron.ParseStandard works but a custom NewParser call forgot Descriptor; upgrading or replacing cron.Parse with a hand-rolled NewParser and losing descriptor support; user-submitted specs containing @strings.","solutions":["Add cron.Descriptor to the NewParser option mask","Strip/handle @descriptors in caller code before Parse when descriptors should be unsupported","Use cron.ParseStandard instead of a custom NewParser if standard behavior is desired"],"exampleFix":"// before\np := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)\ns, err := p.Parse(\"@daily\") // error\n// after\np := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)\ns, err := p.Parse(\"@daily\")","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(spec, \"@\") && parserOptions&cron.Descriptor == 0 {\n\treturn fmt.Errorf(\"descriptors like %q require the Descriptor parser option\", spec)\n}","typeGuard":null,"tryCatchPattern":"sched, err := parser.Parse(spec)\nif err != nil && strings.HasPrefix(spec, \"@\") {\n\treturn fmt.Errorf(\"descriptor unsupported by this parser: %w\", err)\n}","preventionTips":["Always include cron.Descriptor in custom NewParser masks if users supply specs","Keep option masks in sync with cron.ParseStandard when migrating","Test @-descriptor specs against your parser configuration"],"tags":["go","cron","parser","configuration","descriptors"],"backgroundTag":"feature-not-enabled","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"}