aaif-goose/goose · warning
Expected 5 or 6 fields
Error message
Expected 5 or 6 fields
What it means
describeCron() splits the cron expression on whitespace and only hands 5-field (standard) or 6-field (with seconds) expressions to cronstrue. Any other field count — 4, 7+, or an empty-ish string that still splits to the wrong count — throws 'Expected 5 or 6 fields' before cronstrue ever runs. Note parseCron() is more forgiving (it returns a 'custom' period via normalizeCronParts returning null), so this is specific to the human-readable description path.
Source
Thrown at ui/desktop/src/utils/cronSchedule.ts:90
}
const parsedDay = parseInt(value, 10);
if (parsedDay < 1 || parsedDay > max) {
return null;
}
return parsedDay.toString();
};
const asCustomCron = (parts: string[]): ParsedCron => {
const [second, minute, hour, dayOfMonth, month, dayOfWeek] = parts;
return { period: 'custom', second, minute, hour, dayOfMonth, month, dayOfWeek };
};
export const describeCron = (cron: string): string => {
const parts = cron.trim().split(/\s+/);
if (parts.length === 5 || parts.length === 6) {
return cronstrue.toString(parts.join(' '));
}
throw new Error('Expected 5 or 6 fields');
};
export const parseCron = (cron: string): ParsedCron => {
if (!cron.trim()) {
return defaultParsedCron;
}
const parts = normalizeCronParts(cron);
if (!parts) {
return { ...defaultParsedCron, period: 'custom' };
}
const [second, minute, hour, dayOfMonth, month, dayOfWeek] = parts;
if (!isSingleNumericValue(second)) {
return asCustomCron(parts);
}
View on GitHub (pinned to 3810898a74)
Solutions
- Normalize the expression to exactly 5 fields (minute hour dom month dow) or 6 with a leading seconds field before calling describeCron
- Expand named schedules (@daily, @hourly) to their field form first
- Strip appended timezone/extra tokens before passing the string
- Prefer parseCron()+field-level rendering for arbitrary user input; it never throws this error
Example fix
// before
describeCron('0 0 12 * * ? 2026'); // 7 fields -> throws
// after
describeCron('0 12 * * ?'); // 6 fields (sec min hour dom mon dow) Defensive patterns
Strategy: type-guard
Validate before calling
const fields = cron.trim().split(/\s+/).filter(Boolean);
if (fields.length !== 5 && fields.length !== 6) {
// reject/normalize input before describeCron
return 'Invalid schedule';
} Type guard
const isFiveOrSixFieldCron = (cron: string): boolean => {
const n = cron.trim().split(/\s+/).filter(Boolean).length;
return n === 5 || n === 6;
}; Try / catch
try {
label = describeCron(cron);
} catch (e) {
if (e instanceof Error && e.message === 'Expected 5 or 6 fields') {
label = cron; // show raw expression instead of crashing the settings UI
} else throw e;
} Prevention
- Validate field count at the form input, not at render time
- Convert @daily/@hourly macros to fields before describing
- Reuse parseCron for user input; it degrades to 'custom' instead of throwing
When it happens
Trigger: Calling describeCron('0 0 * * * * *') (7 fields, e.g. Quartz with year); describeCron('0 12 * *') (missing a field); describeCron('@daily') (named schedules are not expanded here); double-space strings are fine (split on \s+) but stray tokens like trailing words break the count.
Common situations: Schedules UI receiving user-typed cron; migrated data containing Quartz 7-field expressions; copy-paste from tutorials with @hourly macros; schedulers that prefix or append extra tokens (timezone names like 'UTC' as a 6th/7th word).
Related errors
- Resource '${fallbackUri}' returned no contents
- Unknown provider: ${providerId}
- Unsupported extension type for ACP: ${config.type}
- External ACP backend URL is required
- External ACP backend URL must use http: or https:, got ${url
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/8c841ffda0f13b13.
Report an issue: GitHub.