garrytan/gstack · error · Error
${hostConfig.displayName} description for "${name}" is ${des
Error message
${hostConfig.displayName} description for "${name}" is ${description.length} chars (max ${fm.descriptionLimit}). Compress the description in the .tmpl file. What it means
Host-specific frontmatter description length limit exceeded. When frontmatter.descriptionLimit is set and descriptionLimitBehavior === 'error' (the default), the generator throws rather than producing oversized frontmatter. The limit comes from the host config (fm.descriptionLimit) and the offending skill name + lengths are included.
Source
Thrown at scripts/gen-skill-docs.ts:546
}
return content;
}
// Allowlist mode: reconstruct frontmatter with only allowed fields
const fmStart = content.indexOf('---\n');
if (fmStart !== 0) return content;
const fmEnd = content.indexOf('\n---', fmStart + 4);
if (fmEnd === -1) return content;
const frontmatter = content.slice(fmStart + 4, fmEnd);
const body = content.slice(fmEnd + 4);
const { name, description } = extractNameAndDescription(content);
// Description limit enforcement
if (fm.descriptionLimit) {
const behavior = fm.descriptionLimitBehavior || 'error';
if (description.length > fm.descriptionLimit) {
if (behavior === 'error') {
throw new Error(
`${hostConfig.displayName} description for "${name}" is ${description.length} chars (max ${fm.descriptionLimit}). ` +
`Compress the description in the .tmpl file.`
);
} else if (behavior === 'warn') {
console.warn(`WARNING: ${hostConfig.displayName} description for "${name}" exceeds ${fm.descriptionLimit} chars`);
}
// 'truncate' — silently proceed
}
}
// Build frontmatter with allowed fields
const indentedDesc = description.split('\n').map(l => ` ${l}`).join('\n');
let newFm = `---\nname: ${name}\ndescription: |\n${indentedDesc}\n`;
// Add extra fields (host-wide)
if (fm.extraFields) {
for (const [key, value] of Object.entries(fm.extraFields)) {
if (key !== 'name' && key !== 'description') {View on GitHub (pinned to 94993f7401)
Solutions
- Compress the description in the .tmpl file to one lead sentence
- Move routing/voice detail into a body `## When to invoke` section (catalog-mode=trim does this automatically)
- If the longer description is intentional and supported, set descriptionLimitBehavior: 'warn' for that host
- Split the skill into smaller, focused skills
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'fs';
const content = readFileSync(tmplPath, 'utf-8');
const desc = extractNameAndDescription(content).description;
if (fm.descriptionLimit && desc.length > fm.descriptionLimit && (fm.descriptionLimitBehavior || 'error') === 'error') {
console.error(`Description for ${tmplPath} is ${desc.length} chars (max ${fm.descriptionLimit}); trim before building`);
process.exit(2);
} Prevention
- Keep .tmpl descriptions to a single lead sentence
- Run `bun run gen:skill-docs` locally before committing description edits
- Use catalog-mode=trim so routing detail moves to the body
- Watch multi-host builds: the strictest host's limit wins
When it happens
Trigger: Adding prose to a .tmpl description that pushes over the host's limit (e.g. Codex caps at 1024). Generating for a host with a tighter limit than tested locally. descriptionLimitBehavior set to 'error' on a verbose skill.
Common situations: Editing a .tmpl description to add a use case. Multi-host build where one host's limit is stricter. Accumulating description bloat across versions.
Related errors
- gen-llms-txt: ${t.tmpl} is missing name or description in fr
- Codex description for "${name}" is ${description.length} cha
- Unknown placeholder {{${resolverName}}} in ${relTmplPath}
- Unresolved placeholders in ${relTmplPath}: ${remaining.join(
- {{LEARNINGS_SEARCH:query=...}} value must match ${QUERY_SAFE
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/1e0278203139b05a.
Report an issue: GitHub.