robfig/cron · error

unrecognized descriptor

Error message

unrecognized descriptor: %s

What it means

Thrown by parseDescriptor in parser.go when the schedule string starts with '@' but doesn't match any supported descriptor (@yearly, @annually, @monthly, @weekly, @daily, @midnight, @hourly, or the '@every <duration>' prefix). Parse routes any '@'-prefixed string here first, so unknown at-directives fall through to this error.

Solutions

  1. Check spelling and case — descriptors are lowercase and exact: @yearly, @annually, @monthly, @weekly, @daily, @midnight, @hourly
  2. For interval schedules use the exact prefix '@every ' (with a space) followed by a valid duration, e.g. '@every 5m'
  3. Note '@reboot' is unsupported; register the job explicitly at startup instead
  4. Validate user-supplied schedule strings with cron.Parse before storing them

Example fix

// before
cron.Parse("@reboot") // not a supported descriptor
// after
cron.Parse("@daily") // or run the job directly in main()
Defensive patterns

Strategy: validation

Validate before calling

var descriptors = map[string]bool{"@yearly":true,"@annually":true,"@monthly":true,"@weekly":true,"@daily":true,"@midnight":true,"@hourly":true}
func knownDescriptor(s string) bool {
	return descriptors[s] || strings.HasPrefix(s, "@every ")
}

Try / catch

sched, err := cron.Parse(spec)
if err != nil {
	return fmt.Errorf("invalid cron spec %q: %w", spec, err)
}

Prevention

When it happens

Trigger: Calling cron.Parse with unsupported or misspelled descriptors: '@every' (missing space), '@ever 5m', '@reboot', '@hourIy' (uppercase I), '@Yearly' (case-sensitive switch), or custom at-syntax like '@interval 10m' that this library doesn't define.

Common situations: Migrating from Vixie cron which supports '@reboot'; copying Quartz or other scheduler directives; typos or capitalization differences; building the descriptor dynamically and forgetting the mandatory space in '@every '; users entering free-form schedule text in a UI.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of robfig/cron@bc59245fe1 (2026-09-07). Data as JSON: /api/errors/6ee065678a2ff352. Report an issue: GitHub.

Appendix: source

Thrown at parser.go:433

			Hour:     all(hours),
			Dom:      all(dom),
			Month:    all(months),
			Dow:      all(dow),
			Location: loc,
		}, nil

	}

	const every = "@every "
	if strings.HasPrefix(descriptor, every) {
		duration, err := time.ParseDuration(descriptor[len(every):])
		if err != nil {
			return nil, fmt.Errorf("failed to parse duration %s: %s", descriptor, err)
		}
		return Every(duration), nil
	}

	return nil, fmt.Errorf("unrecognized descriptor: %s", descriptor)
}

View on GitHub (pinned to bc59245fe1)