affaan-m/ECC · error · Error
spec.schedule[ ] must be a dense six-cell array
Error message
spec.schedule[${rowIndex}] must be a dense six-cell array What it means
Each element of spec.schedule must be a dense array of exactly six cells. The renderer iterates rows and rejects any row that is not an array, has length !== 6, or contains sparse holes (Object.hasOwn check fails for an index). The thrown message names the offending row index.
Solutions
- Make every row exactly six cells: pad missing cells with '' or 0, and trim extras.
- Build rows with Array.of(...) or a literal so all six indices are own properties (no holes).
- If a cell is optional, pass an empty string rather than deleting the slot.
- Pre-validate: rows.every(r => Array.isArray(r) && r.length === 6 && Object.hasOwn(r, 5)).
Example fix
// before const row = new Array(6); row[0] = 'monday'; // sparse row // after const row = ['monday', '09:00', '17:00', 'lunch', 60, '']; // dense six-cell row
Defensive patterns
Strategy: validation
Validate before calling
function assertDenseRows(schedule) {
schedule.forEach((row, i) => {
if (!Array.isArray(row) || row.length !== 6 || !Object.hasOwn(row, 5)) {
throw new TypeError(`spec.schedule[${i}] must be a dense six-cell array`);
}
});
} Type guard
const isDenseSixCellRow = (r) => Array.isArray(r) && r.length === 6 && Object.hasOwn(r, 5);
Try / catch
try {
buildAgreement(spec);
} catch (e) {
const m = e.message.match(/spec\.schedule\[(\d+)\]/);
if (m) {
const i = Number(m[1]);
spec.schedule = spec.schedule.map((r, idx) =>
idx === i ? padOrTrimRow(r, 6) : r);
return buildAgreement(spec);
}
throw e;
} Prevention
- Build rows with array literals or Array.of, never `new Array(6)` (creates holes).
- Pad short rows with '' and trim long rows to 6 before building.
- Add a unit test asserting every exported row passes isDenseSixCellRow.
When it happens
Trigger: spec.schedule = [['a','b','c']] (three cells), spec.schedule = [row0, null], spec.schedule with a deleted index creating a hole (sparse array), or a row built with `new Array(6)` without filling all slots.
Common situations: Editing a spreadsheet-exported row and dropping a column; programmatically building rows with Array(6) (sparse) instead of Array.from/fill; merging rows of differing widths; optional trailing cells removed making the row short.
Related errors
- built an invalid spec
- Canonical session snapshot requires
- Canonical session snapshot requires workers to be an array
- spec.schedule must be an array of six-cell rows
- -32602
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/bee494b54e75b0a4.
Report an issue: GitHub.
Appendix: source
Thrown at skills/master-agreement-generator/scripts/build-agreement.js:65
// 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');
}
function buildValues(spec, now) {
if (!spec || typeof spec !== 'object') {
throw new Error('spec must be an object');
}
for (const key of ['file', 'short', 'role']) {View on GitHub (pinned to 8321021c54)