ruvnet/ruflo · error

Unknown built-in skill: ${skillName}

Error message

Unknown built-in skill: ${skillName}

What it means

generateBuiltInSkill(name) reads one of the packaged .agents/skills trees as the canonical definition. Only six names are accepted: swarm-orchestration, memory-management, sparc-methodology, security-audit, performance-analysis, github-automation. Any other string — a typo, different casing, a custom name, or a skill that exists only in another version — fails validation before any file is read.

Source

Thrown at v3/@claude-flow/codex/src/generators/skill-md.ts:182

        }
        const payloadPath = relative.split(path.sep).join('/');
        payload[payloadPath] = await readFile(absolute, 'utf8');
      }
    }
  }

  await visit(root);
  return payload;
}

/**
 * Read one canonical built-in tree from the package payload.
 */
export async function generateBuiltInSkill(
  skillName: string,
): Promise<{ skillMd: string; scripts: Record<string, string>; references: Record<string, string> }> {
  if (!BUILT_IN_SKILL_NAMES.includes(skillName as BuiltInSkill)) {
    throw new Error(`Unknown built-in skill: ${skillName}`);
  }

  const skillRoot = path.join(BUILT_IN_SKILLS_ROOT, skillName);
  let skillMd: string;
  try {
    skillMd = await readFile(path.join(skillRoot, 'SKILL.md'), 'utf8');
  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
      throw new Error(`Built-in skill payload missing: ${skillName}/SKILL.md`);
    }
    throw error;
  }

  const result = {
    skillMd,
    scripts: await readPayloadTree(path.join(skillRoot, 'scripts')),
    references: await readPayloadTree(path.join(skillRoot, 'references')),
  };

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Pass one of the six exported names exactly: swarm-orchestration, memory-management, sparc-methodology, security-audit, performance-analysis, github-automation
  2. Import BUILT_IN_SKILL_NAMES from the package and validate or offer them for selection instead of hardcoding name strings
  3. For anything not on the list, render a custom skill with generateSkillMd(options) instead of generateBuiltInSkill

Example fix

// before
const payload = await generateBuiltInSkill('security-audits'); // typo

// after
const payload = await generateBuiltInSkill('security-audit');
// or, for a custom skill:
const md = await generateSkillMd({ name: 'security-audits', description: '...' });
Defensive patterns

Strategy: type-guard

Validate before calling

import { BUILT_IN_SKILL_NAMES } from '@claude-flow/codex';
const builtIn = new Set<string>(BUILT_IN_SKILL_NAMES);
function assertBuiltInSkill(name: string): void {
  if (!builtIn.has(name)) {
    throw new Error(`unknown built-in skill ${name}; valid: ${[...builtIn].join(', ')}`);
  }
}

Type guard

import { BUILT_IN_SKILL_NAMES, type BuiltInSkill } from '@claude-flow/codex';
const builtIn = new Set<string>(BUILT_IN_SKILL_NAMES);
function isBuiltInSkill(name: string): name is BuiltInSkill {
  return typeof name === 'string' && builtIn.has(name);
}

Prevention

When it happens

Trigger: Calling generateBuiltInSkill('security-audits') (typo), 'Security-Audit' (casing), or any custom skill name; calling it with a name valid in a different @claude-flow/codex version whose BUILT_IN_SKILL_NAMES list differs.

Common situations: User- or CLI-supplied skill names passed through unvalidated; upgrading or downgrading the package where the built-in list changed; confusing custom skills (generated with generateSkillMd) with built-in payload skills.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/3dfcda2ed85eac09. Report an issue: GitHub.