affaan-m/ECC · error · Error
${source} is missing the catalog count description
Error message
${source} is missing the catalog count description What it means
After JSON-parsing succeeds, `parseCatalogDescriptionExpectations` calls `getDescription(parsed)` and checks `typeof description !== 'string'`. For plugin.json this reads `parsed.description`; for marketplace.json it reads `parsed.plugins?.[0]?.description`. If the field is missing, undefined, null, or a non-string, the throw fires with `${source} is missing the catalog count description`. This is distinct from error 32 (which fires when the description string exists but lacks the count pattern).
Source
Thrown at scripts/ci/catalog.js:341
expected: Number(match[1]),
source: `${pattern.source} (${pattern.category})`
});
}
return expectations;
}
function parseCatalogDescriptionExpectations(content, source, getDescription) {
let parsed;
try {
parsed = JSON.parse(content);
} catch (error) {
throw new Error(`${source} is not valid JSON: ${error.message}`);
}
const description = getDescription(parsed);
if (typeof description !== 'string') {
throw new Error(`${source} is missing the catalog count description`);
}
const match = description.match(/(\d+)\s+agents,\s+(\d+)\s+skills,\s+(\d+)\s+legacy command shims?/i);
if (!match) {
throw new Error(`${source} is missing the catalog count description`);
}
return [
{ category: 'agents', mode: 'exact', expected: Number(match[1]), source },
{ category: 'skills', mode: 'exact', expected: Number(match[2]), source },
{ category: 'commands', mode: 'exact', expected: Number(match[3]), source },
];
}
function evaluateExpectations(catalog, expectations) {
return expectations.map(expectation => {
const actual = catalog[expectation.category].count;
const ok = expectation.mode === 'minimum'View on GitHub (pinned to 01e15490f0)
Solutions
- For plugin.json: ensure a top-level `"description": "..."` string key exists.
- For marketplace.json: ensure `plugins[0].description` is a string — verify the plugins array is non-empty and index 0 is the intended plugin.
- The description string must contain the count pattern `N agents, N skills, N legacy command shims` (see error 32) once restored.
- Run `node scripts/ci/catalog.js --write` to populate/sync the description counts after restoring the field.
Example fix
// before (.claude-plugin/marketplace.json — empty plugins array)
{
"plugins": []
}
// after
{
"plugins": [
{
"name": "ecc",
"description": "ECC plugin — 68 agents, 284 skills, 94 legacy command shims"
}
]
} Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
function checkDesc(file, getterDesc) {
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
let obj = parsed;
for (const key of getterDesc) {
if (obj == null || typeof obj !== 'object') { console.error(`${file}: missing ${getterDesc.join('.')}`); process.exit(1); }
obj = obj[key];
}
if (typeof obj !== 'string') { console.error(`${file}: ${getterDesc.join('.')} is not a string`); process.exit(1); }
}
checkDesc('.claude-plugin/plugin.json', ['description']);
checkDesc('.claude-plugin/marketplace.json', ['plugins', '0', 'description']); Type guard
function hasDescriptionField(parsed, marketplace) {
if (!marketplace) return typeof parsed?.description === 'string';
return Array.isArray(parsed?.plugins) && parsed.plugins.length > 0 && typeof parsed.plugins[0]?.description === 'string';
} Try / catch
try {
runCatalogCheck();
} catch (error) {
if (/is missing the catalog count description/i.test(error.message)) {
console.error('Add a string description field (plugin.json: description; marketplace.json: plugins[0].description) containing the count pattern.');
}
throw error;
} Prevention
- Ensure plugin.json always has a top-level string `description`.
- Ensure marketplace.json has a non-empty plugins array with plugins[0].description as a string.
- Validate the manifest shape in CI with a JSON schema.
- Run `--write` only after the description field exists — it will not create the field for you.
When it happens
Trigger: Fires when `.claude-plugin/plugin.json` has no `description` key, or `.claude-plugin/marketplace.json` has no `plugins` array, an empty `plugins` array, or `plugins[0]` has no `description` key. Also fires if description is explicitly null or a number.
Common situations: plugin.json is regenerated by a scaffolder that omits description. marketplace.json's plugins array is reordered and index 0 now points at a different plugin without a description. The description field is renamed (e.g. to `summary`). The plugins array is empty after a cleanup.
Related errors
- ${source} is not valid JSON: ${error.message}
- Invalid JSON in ${label}: ${error.message}
- README.md project tree is missing the agents count
- ${pattern.source} is missing the ${pattern.category} row
- README.zh-CN.md is missing the quick-start catalog summary
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/ffa52c64ad9b6c55.
Report an issue: GitHub.