CLI throws TypeError when skill description is not a string

Resolved 💬 4 comments Opened Jan 8, 2026 by ai-cora Closed Jan 8, 2026

CLI throws TypeError when skill description is not a string

Description

Claude Code CLI throws an unhandled exception when a skill's YAML frontmatter has a description field that isn't a string. The error corrupts the terminal UI (multiple input prompts appear) and breaks command palette functionality until the malformed skill is removed.

<img width="2551" height="1381" alt="Image" src="https://github.com/user-attachments/assets/83b4c3fb-b474-474d-8c34-e684a76289f0" />

Steps to Reproduce

  1. Create a skill file ~/.claude/skills/test-skill/SKILL.md:
---
name: test-skill
description: [This is parsed as an array, not a string]
---

# Test Skill
  1. Start Claude Code
  2. Type /con (start typing a slash command to trigger fuzzy search)
  3. TypeError is thrown and UI becomes corrupted

Error Message

TypeError: X.description.split is not a function
    at file:///Users/admin/.nvm/versions/node/v22.21.1/lib/node_modules/@anthropic-ai/claude-code/cli.js:3061:27343
    at Array.map (<anonymous>)
    at cN0 (file:///Users/admin/.nvm/versions/node/v22.21.1/lib/node_modules/@anthropic-ai/claude-code/cli.js:3061:27231)
    at file:///Users/admin/.nvm/versions/node/v22.21.1/lib/node_modules/@anthropic-ai/claude-code/cli.js:3064:14351

Root Cause Analysis

In the minified cli.js at line 3061, position ~27343, the code builds a Fuse.js search index:

descriptionKey:X.description.split(" ").map((K)=>I47(K)).filter(Boolean)

This assumes description is always a string. In YAML, square brackets [...] denote an array, so:

description: [TODO: Write description]  # Parsed as array, not string!

This is an easy mistake to make because text with brackets can look syntactically correct.

Quick Reproduction

# Create temp project with malformed skill, run claude, cleanup on exit
d=$(mktemp -d) && mkdir -p "$d/.claude/skills/bad"
echo -e "---\nname: bad\ndescription: [array]\n---\n# Bad" > "$d/.claude/skills/bad/SKILL.md"
cd "$d" && claude; rm -rf "$d"
# Then type /con to trigger error

Full reproduction scripts available:

Suggested Fix

The codebase already uses Zod for schema validation extensively. Adding validation during skill load would be consistent with existing patterns:

Option 1: Early Validation (Recommended)

Add Zod schema validation when parsing skill frontmatter:

const skillFrontmatterSchema = z.object({
  name: z.string().min(1),
  description: z.string().min(1, "Description must be a string"),
  // ...
});

const parsed = skillFrontmatterSchema.safeParse(frontmatter);
if (!parsed.success) {
  console.warn(`Skipping skill ${filePath}: ${parsed.error.message}`);
  return null;
}

Option 2: Defensive Coercion

Simple fix at the search index builder:

// Before
descriptionKey: X.description.split(" ").map(...)

// After
descriptionKey: String(X.description || "").split(" ").map(...)

Option 1 is better because it validates early and provides clear error messages pointing to the problematic file.

Impact

  • Severity: High - Command palette breaks and UI becomes corrupted
  • Scope: Any user who creates a skill with accidentally malformed YAML
  • Discoverability: Low - The error message doesn't indicate which skill file is problematic

Workaround

Quote the description in the YAML frontmatter:

description: "Text with [brackets] needs quotes"

Environment

  • Claude Code version: 2.1.1
  • Node.js: v22.21.1
  • OS: macOS 15.3 (Darwin 25.2.0)

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗