yamadashy/repomix · error

Skill name cannot be empty after normalization

Error message

Skill name cannot be empty after normalization

What it means

After converting to kebab-case, validateSkillName checks that the result is non-empty and throws if normalization erased every character (e.g. input made entirely of characters stripped by toKebabCase like '///' or '--'). It guarantees the generated skill directory name is usable.

Source

Thrown at src/core/skill/skillUtils.ts:40

 * Validates and normalizes a skill name.
 * Converts to kebab-case and truncates to 64 characters.
 * Also rejects path traversal attempts.
 */
export const validateSkillName = (name: string): string => {
  // Reject path separators and null bytes to prevent path traversal
  if (name.includes('/') || name.includes('\\') || name.includes('\0')) {
    throw new Error('Skill name cannot contain path separators or null bytes');
  }

  // Reject dot-only names (., .., ...)
  if (/^\.+$/.test(name)) {
    throw new Error('Skill name cannot consist only of dots');
  }

  const kebabName = toKebabCase(name);

  if (kebabName.length === 0) {
    throw new Error('Skill name cannot be empty after normalization');
  }

  return kebabName.substring(0, SKILL_NAME_MAX_LENGTH);
};

/**
 * Converts a string to Title Case.
 * Handles kebab-case, snake_case, and other separators.
 */
const toTitleCase = (str: string): string => {
  return str
    .replace(/[-_]/g, ' ')
    .replace(/\b\w/g, (char) => char.toUpperCase())
    .trim();
};

/**
 * Generates a human-readable project name from root directories.

View on GitHub (pinned to f465ad9093)

Solutions

  1. Check for alphanumeric content before calling and supply a meaningful fallback name.
  2. Improve the input source (e.g. use the repository name rather than a symbolic URL fragment).
  3. Fall back to a default like 'repomix-skill' when the derived name would be empty.

Example fix

// before
const name = validateSkillName(title); // title = '### !!!'
// after
const fallback = title && toKebabCase(title).length > 0 ? title : 'repomix-skill';
const name = validateSkillName(fallback);
Defensive patterns

Strategy: fallback

Validate before calling

const derived = toKebabCase(raw);
const name = validateSkillName(derived.length > 0 ? raw : 'repomix-skill');

Type guard

const hasNameableContent = (s: string): boolean => /[a-z0-9]/i.test(s);

Try / catch

try {
  const name = validateSkillName(input);
} catch (e) {
  if (e.message.includes('empty after normalization')) {
    const name = validateSkillName('repomix-skill');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a name whose kebab-case transformation yields an empty string — e.g. only symbols/punctuation, whitespace-only, or characters removed by the normalization pipeline.

Common situations: Auto-deriving names from URLs or titles that are pure punctuation/emoji; locale-specific input where all characters are stripped; an upstream sanitizer that already removed alphanumerics.

Related errors


AI-assisted analysis of yamadashy/repomix@f465ad9093 (2026-08-29). Data as JSON: /api/errors/a37ab62a98b4b64c. Report an issue: GitHub.