affaan-m/ECC · error · Error
${pattern.source} is missing the ${pattern.category} row
Error message
${pattern.source} is missing the ${pattern.category} row What it means
This throw occurs inside the loop over `tablePatterns` in `parseReadmeExpectations`. The script scans README.md's comparison table for three markdown rows — Agents, Commands, Skills — each expected in the form `| Agents | 68 agents |`. If any single row's regex fails to match, the error names which source (`README.md comparison table`) and which category is missing. All three counts feed the cross-document consistency check.
Source
Thrown at scripts/ci/catalog.js:125
}
expectations.push({
category: 'agents',
mode: 'exact',
expected: Number(projectTreeAgentsMatch[1]),
source: 'README.md project tree (agents)'
});
const tablePatterns = [
{ category: 'agents', regex: /\|\s*(?:\*\*)?Agents(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+agents\s*\|/i, source: 'README.md comparison table' },
{ category: 'commands', regex: /\|\s*(?:\*\*)?Commands(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+commands(?:\s*\([^)]*\))?\s*\|/i, source: 'README.md comparison table' },
{ category: 'skills', regex: /\|\s*(?:\*\*)?Skills(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+skills\s*\|/i, source: 'README.md comparison table' }
];
for (const pattern of tablePatterns) {
const match = readmeContent.match(pattern.regex);
if (!match) {
throw new Error(`${pattern.source} is missing the ${pattern.category} row`);
}
expectations.push({
category: pattern.category,
mode: 'exact',
expected: Number(match[1]),
source: `${pattern.source} (${pattern.category})`
});
}
return expectations;
}
function parseZhRootReadmeExpectations(readmeContent) {
const match = readmeContent.match(/你现在可以使用\s+(\d+)\s+个代理、\s*(\d+)\s*个技能和\s*(\d+)\s*个命令/i);
if (!match) {
throw new Error('README.zh-CN.md is missing the quick-start catalog summary');
}View on GitHub (pinned to 01e15490f0)
Solutions
- Open README.md and restore the missing row to the exact form `| Agents | N agents |` (or `| Commands | N commands |` / `| Skills | N skills |`), matching the regex which tolerates optional `**` bold and optional `PASS:`/`✅` prefixes.
- Run `node scripts/ci/catalog.js --write` to let the sync functions rewrite all documented counts from the live catalog.
- Confirm the row lives in a markdown table (pipe-delimited) and the unit word follows the number with a single space.
- Re-run `node scripts/ci/catalog.js` to confirm all three rows now match.
Example fix
// before (README.md comparison table, skills row dropped) | **Agents** | 68 agents | | **Commands** | 94 commands | // after | **Agents** | 68 agents | | **Commands** | 94 commands | | **Skills** | 284 skills |
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
const readme = fs.readFileSync('README.md', 'utf8');
const rows = [
{ cat: 'agents', re: /\|\s*(?:\*\*)?Agents(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+agents\s*\|/i },
{ cat: 'commands', re: /\|\s*(?:\*\*)?Commands(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+commands(?:\s*\([^)]*\))?\s*\|/i },
{ cat: 'skills', re: /\|\s*(?:\*\*)?Skills(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+skills\s*\|/i },
];
for (const { cat, re } of rows) {
if (!re.test(readme)) {
console.error(`README.md comparison table missing ${cat} row`);
process.exit(1);
}
} Type guard
function hasComparisonTableRow(readmeContent, category) {
const map = {
agents: /\|\s*(?:\*\*)?Agents(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+agents\s*\|/i,
commands: /\|\s*(?:\*\*)?Commands(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+commands(?:\s*\([^)]*\))?\s*\|/i,
skills: /\|\s*(?:\*\*)?Skills(?:\*\*)?\s*\|\s*(?:(?:PASS:|\u2705)\s*)?(\d+)\s+skills\s*\|/i,
};
const m = readmeContent.match(map[category]);
return m !== null && Number.isInteger(Number(m[1]));
} Try / catch
try {
runCatalogCheck();
} catch (error) {
if (/comparison table is missing the .* row/i.test(error.message)) {
console.error('Restore the markdown table row with the exact unit word (agents/commands/skills) after the count.');
console.error('Run: node scripts/ci/catalog.js --write');
}
throw error;
} Prevention
- Keep the unit word (agents/commands/skills) immediately after the count in every comparison-table row.
- Do not strip the `PASS:`/emoji prefix or the bold markers without re-testing the regex.
- Run `--write` instead of hand-editing counts.
- After any table reformat, run the catalog check before committing.
When it happens
Trigger: Triggered by `node scripts/ci/catalog.js` when the comparison-table section of README.md is missing the Agents, Commands, or Skills row, or the row's wording deviates (e.g. `| **Agents** | 68 |` without the trailing `agents` unit word, or `68` spelled out, or a `PASS:`/emoji prefix in an unexpected position). The check fires per-row, so only the first missing row is reported.
Common situations: The comparison table is reformatted to remove unit words (`agents`, `commands`, `skills`). A row is deleted during a table consolidation. Counts are updated by hand but the unit suffix is dropped. The table is moved to a different doc without updating README.
Related errors
- README.md project tree is missing the agents count
- README.zh-CN.md is missing the quick-start catalog summary
- docs/zh-CN/README.md is missing the quick-start catalog summ
- AGENTS.md is missing the catalog summary line
- ${pattern.source} is missing the ${pattern.category} entry
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/34901276574aa82a.
Report an issue: GitHub.