affaan-m/ECC · error · Error
spec.schedule must be an array of six-cell rows
Error message
spec.schedule must be an array of six-cell rows
What it means
renderScheduleRows renders spec.schedule into a markdown table row set. If spec.schedule is present but not an array, the builder rejects it immediately. The library distinguishes 'undefined' (renders a default empty schedule row) from a wrongly-typed value, which is treated as a specification error.
Solutions
- Change spec.schedule to an array of rows, each row itself an array of exactly six cells.
- If the intent is no schedule, omit the field entirely (undefined) rather than passing a wrong type.
- Validate the spec with Array.isArray(spec.schedule) before building.
- Check the spec file's syntax: a missing dash/bracket in YAML can turn an array into a scalar or mapping.
Example fix
// before
const spec = { schedule: { monday: ['09:00', ...] } };
// after
const spec = { schedule: [['monday', '09:00', '17:00', 'break', '60', 'note']] }; // array of six-cell rows Defensive patterns
Strategy: validation
Validate before calling
function assertScheduleArray(spec) {
if (spec.schedule !== undefined && !Array.isArray(spec.schedule)) {
throw new TypeError('spec.schedule must be an array of six-cell rows (or omitted)');
}
} Type guard
const isSchedule = (s) => s === undefined || (Array.isArray(s) && s.every(Array.isArray));
Try / catch
try {
buildAgreement(spec);
} catch (e) {
if (e.message.includes('spec.schedule must be an array')) {
spec = { ...spec, schedule: normalizeSchedule(spec.schedule) };
return buildAgreement(spec);
}
throw e;
} Prevention
- Validate spec files with a JSON/YAML schema requiring schedule: array of arrays.
- In YAML specs, double-check indentation — a lost dash turns an array into a mapping.
- Omit the field entirely for 'no schedule' instead of passing a placeholder object or string.
When it happens
Trigger: Calling buildValues/build-agreement with a spec where schedule is a non-array value — e.g. a string 'monday', an object { rows: [...] }, a Map, or JSON where schedule was meant to be an array of arrays.
Common situations: Hand-written YAML/JSON spec where the schedule was written as an object or string; a loader that collapsed the array; copy-pasting a single row (object) instead of an array of rows; schema drift after editing the spec generator.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- built an invalid spec
- Canonical session snapshot must be an object
- Canonical session snapshot requires
- Canonical session snapshot requires
- Canonical session snapshot requires
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/148adf941e3b69a2.
Report an issue: GitHub.
Appendix: source
Thrown at skills/master-agreement-generator/scripts/build-agreement.js:60
return now.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
}
function encodeScheduleCell(cell) {
const entity = character => `&#${character.codePointAt(0)};`;
// Entities keep data out of Markdown/HTML syntax, including smart punctuation.
// Preserve single internal spaces and ordinary dates/example text as written.
return String(cell).replace(/\r\n|\r|\n/g, ' ')
.replace(/[\\|`*_{}[\]<>!&#~^$'"@]/g, entity)
.replace(/-{2,}|\.{3,}/g, run => [...run].map(entity).join(''))
.replace(/^ +| +$| {2,}|[^\S ]/gu, run => [...run].map(entity).join(''));
}
function renderScheduleRows(rows) {
if (rows === undefined) {
return EMPTY_SCHEDULE_ROW;
}
if (!Array.isArray(rows)) {
throw new Error('spec.schedule must be an array of six-cell rows');
}
if (rows.length === 0) return EMPTY_SCHEDULE_ROW;
return Array.from(rows, (row, rowIndex) => {
if (!Object.hasOwn(rows, rowIndex) || !Array.isArray(row) || row.length !== 6) {
throw new Error(`spec.schedule[${rowIndex}] must be a dense six-cell array`);
}
const cells = Array.from(row, (cell, cellIndex) => {
if (!Object.hasOwn(row, cellIndex) ||
!((typeof cell === 'string' && !/\p{Surrogate}/u.test(cell)) ||
(typeof cell === 'number' && Number.isFinite(cell)))) {
throw new Error(`spec.schedule[${rowIndex}][${cellIndex}] must be valid Unicode text or a finite number`);
}
return encodeScheduleCell(cell);
});
return `| ${cells.join(' | ')} |`;
}).join('\n');
}
View on GitHub (pinned to 8321021c54)