DietrichGebert/ponytail · error · Error

description for ${name} must be one line, no quotes, under 1

Error message

description for ${name} must be one line, no quotes, under 160 chars

What it means

Thrown by render() in scripts/build-openclaw-skills.js. Before embedding a description into the canonical frontmatter, render() validates the DESCRIPTIONS[name] string: length must be <= 160 chars, it must contain no newline (single line), and it must contain no double-quote character (because the description is emitted wrapped in double quotes as description: "${desc}"). Any violation throws, since a malformed description would produce broken YAML frontmatter in the generated .openclaw skill bundle.

Source

Thrown at scripts/build-openclaw-skills.js:40

  'ponytail-audit': 'Audit the whole repo for over-engineering. A ranked list of what to delete, simplify, or replace with stdlib or native features.',
  'ponytail-debt': 'Harvest every ponytail: shortcut comment into one debt ledger, so deferrals get tracked instead of forgotten. One-shot report.',
  'ponytail-gain': 'Show ponytail measured impact as a scoreboard: less code, less cost, more speed, from the benchmark medians. One-shot display.',
  'ponytail-help': "Quick reference for ponytail's modes, skills, and commands. One-shot display.",
};

const NAMES = Object.keys(DESCRIPTIONS);

function sourceBody(name) {
  const src = fs.readFileSync(path.join(ROOT, 'skills', name, 'SKILL.md'), 'utf8').replace(/\r\n/g, '\n');
  const fm = src.match(/^---\n[\s\S]*?\n---\n?/);
  if (!fm) throw new Error(`skills/${name}/SKILL.md has no frontmatter`);
  return src.slice(fm[0].length);
}

function render(name) {
  const desc = DESCRIPTIONS[name];
  if (desc.length > 160 || desc.includes('\n') || desc.includes('"')) {
    throw new Error(`description for ${name} must be one line, no quotes, under 160 chars`);
  }
  const frontmatter =
    `---\nname: ${name}\ndescription: "${desc}"\nhomepage: ${HOMEPAGE}\nlicense: MIT\n---\n`;
  return frontmatter + sourceBody(name);
}

function outPath(name) {
  return path.join(ROOT, '.openclaw', 'skills', name, 'SKILL.md');
}

module.exports = { DESCRIPTIONS, NAMES, render, outPath, sourceBody };

if (require.main === module) {
  for (const name of NAMES) {
    const p = outPath(name);
    fs.mkdirSync(path.dirname(p), { recursive: true });
    fs.writeFileSync(p, render(name));
    console.log('wrote', path.relative(ROOT, p).replace(/\\/g, '/'));

View on GitHub (pinned to 2ed6c52c9d)

Solutions

  1. Shorten the offending DESCRIPTIONS[name] value to <= 160 characters on a single line with no double quotes.
  2. Replace any double quotes in the description with single quotes or backticks; remove literal newlines.
  3. Re-run node scripts/build-openclaw-skills.js and confirm render() passes for that skill.

Example fix

// before — scripts/build-openclaw-skills.js
'ponytail-audit': 'Audit the whole repo for over-engineering. A ranked list of what to delete, simplify, or replace with stdlib or native features. "Quick" one-shot report.',

// after — single line, <= 160 chars, no double quotes
'ponytail-audit': 'Audit the whole repo for over-engineering. A ranked list of what to delete, simplify, or replace with stdlib or native features. One-shot report.',
Defensive patterns

Strategy: validation

Validate before calling

// Validate the whole DESCRIPTIONS map at module load, before build runs
function validDescription(d) {
  return typeof d === 'string' && d.length <= 160 && !d.includes('\n') && !d.includes('"');
}
for (const [name, desc] of Object.entries(DESCRIPTIONS)) {
  if (!validDescription(desc)) {
    throw new Error(`${name}: description must be one line, no double quotes, <= 160 chars (got ${desc.length})`);
  }
}

Type guard

function isValidDescription(d) {
  return typeof d === 'string' && d.length > 0 && d.length <= 160 && !d.includes('\n') && !d.includes('"');
}

Try / catch

try {
  render(name);
} catch (e) {
  if (/must be one line/.test(e.message)) {
    console.error(`Fix DESCRIPTIONS['${name}']: <= 160 chars, single line, no double quotes.`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Editing the DESCRIPTIONS object in scripts/build-openclaw-skills.js and adding/altering an entry whose value exceeds 160 characters, spans multiple lines (contains '\n'), or contains a '"' character. Then running node scripts/build-openclaw-skills.js, which iterates NAMES and calls render() on each.

Common situations: A new ponytail skill is added with a verbose one-liner that crosses the 160-char openclaw/skill-registry limit. A description is copy-pasted from prose containing a smart/curly double quote or an actual ASCII double quote. A contributor formats a description across two lines for readability in the source, introducing a literal newline.

Related errors


AI-assisted analysis of DietrichGebert/ponytail@2ed6c52c9d (2026-08-12). Data as JSON: /api/errors/d1dd1f707e598765. Report an issue: GitHub.