upstash/context7 · error
Unsafe skill name
Error message
Unsafe skill name: ${JSON.stringify(skillName)} What it means
Thrown by assertSkillNameInRoot when the requested skill name fails isSafeSkillName (SAFE_NAME regex check — names must be simple, safe identifier-like strings). This is the first line of defense against path traversal via the skill name itself; a second check afterwards also ensures the resolved target is a direct child of the skills root.
Solutions
- Use a plain skill name matching the allowed pattern (letters/digits/dashes, e.g. "my-skill") with no slashes, dots-prefixes, or spaces
- If you have a path or URL, extract just the skill's basename before passing it
- Sanitize or validate user input in scripts before passing it as skillName
- Check what the SAFE_NAME regex in skill-name.ts accepts and conform the name to it
Example fix
// before
await install("../downloaded/skill-pack");
// after
await install("skill-pack"); Defensive patterns
Strategy: validation
Validate before calling
const SAFE_NAME = /^[\w][\w.-]*$/; // mirror the library's SAFE_NAME
if (!SAFE_NAME.test(skillName)) throw new Error(`Refusing unsafe skill name: ${skillName}`); Type guard
function isSafeSkillName(name: string): boolean {
return typeof name === "string" && name.length > 0 && !/[^\w.-]/.test(name) && !name.startsWith(".");
} Try / catch
try {
await installSkill(skillsRoot, rawName);
} catch (e) {
if (e.message.startsWith("Unsafe skill name")) {
console.error(`Invalid skill name '${rawName}'. Use letters, digits, and dashes only.`);
}
} Prevention
- Sanitize CLI/script inputs before using them as skill names
- Extract bare basenames from URLs or paths before passing them
- Document the allowed name pattern for your skill registry users
When it happens
Trigger: Calling any skill operation whose skillName argument contains path separators, `..`, leading dots, spaces, or other characters rejected by SAFE_NAME — e.g. `install("../evil")`, `install("my skill/v2")`, or an empty/oddly-cased name.
Common situations: User-typed skill names from CLI arguments containing typos, slashes, or shell-expanded paths; scripted installs interpolating untrusted input into the name; names copied from URLs that include version paths.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Skill name " " escapes the skills root
- Skill file path " " resolves outside the target directory
- Context7 base URL must not contain a query string or…
- Context7 base URL must not contain credentials
- Expertise description is required
AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16).
Data as JSON: /api/errors/028ce783c8d58c72.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/utils/skill-name.ts:16
import { resolve, dirname, basename } from "path";
const SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
export function isSafeSkillName(name: string): boolean {
if (typeof name !== "string") return false;
if (name.length === 0 || name.length > 128) return false;
if (name === "." || name === "..") return false;
if (name.includes("\0")) return false;
if (!SAFE_NAME.test(name)) return false;
return true;
}
export function assertSkillNameInRoot(skillsRoot: string, skillName: string): string {
if (!isSafeSkillName(skillName)) {
throw new Error(`Unsafe skill name: ${JSON.stringify(skillName)}`);
}
const root = resolve(skillsRoot);
const target = resolve(root, skillName);
if (dirname(target) !== root || basename(target) !== skillName) {
throw new Error(`Skill name "${skillName}" escapes the skills root`);
}
return target;
}
View on GitHub (pinned to 4416fb855b)