upstash/context7 · warning

Failed to install ${skill.name}: ${errMsg}

Error message

Failed to install ${skill.name}: ${errMsg}

What it means

Catch-all in the `context7 skill add` install loop. Permission errors (EACCES/EPERM) are diverted to a dedicated branch that prints chown instructions; any other error thrown while writing skill files or symlinking into agent skill directories (installSkillFiles / symlink steps) is reported here and the batch continues.

Source

Thrown at packages/cli/src/commands/skill.ts:457

          await symlinkSkill(skill.name, primarySkillDir, targetDir);
        } catch (dirErr) {
          const error = dirErr as NodeJS.ErrnoException;
          if (error.code === "EACCES" || error.code === "EPERM") {
            permissionError = true;
            failedDirs.add(targetDir);
          }
          throw dirErr;
        }
      }

      installedSkills.push(`${skill.project}/${skill.name}`);
    } catch (err) {
      const error = err as NodeJS.ErrnoException;
      if (error.code === "EACCES" || error.code === "EPERM") {
        continue;
      }
      const errMsg = err instanceof Error ? err.message : String(err);
      log.warn(`Failed to install ${skill.name}: ${errMsg}`);
    }
  }

  if (permissionError) {
    installSpinner.fail("Permission denied");
    log.blank();
    log.warn("Fix permissions with:");
    for (const dir of failedDirs) {
      const parentDir = join(dir, "..");
      log.dim(`  sudo chown -R $(whoami) "${parentDir}"`);
    }
    log.blank();
    return;
  }

  installSpinner.succeed(`Installed ${installedSkills.length} skill(s)`);
  trackEvent("install", { skills: installedSkills, ides: targets.ides });

View on GitHub (pinned to 5284672feb)

Solutions

  1. Delete stale artifacts: remove the existing skill directory or symlink under the agent's skills path shown in the error, then retry
  2. Recreate the expected skills directory (e.g. mkdir -p ~/.claude/skills) if it was deleted, and re-run
  3. Free disk space or file descriptors if the message shows ENOSPC/EMFILE
  4. Reinstall from a fresh download: `context7 skill search <name> --install`

Example fix

# before — stale symlink causes EEXIST on install
ls -la ~/.claude/skills | grep my-skill

# after — clean and reinstall
rm -rf ~/.claude/skills/my-skill
context7 skill add
Defensive patterns

Strategy: validation

Validate before calling

import { access, constants, lstat, rm } from "node:fs/promises";
import { join } from "node:path";
// before install: writable target dir, no stale artifact
await access(targetDir, constants.W_OK);
const dest = join(targetDir, skillName);
if (await lstat(dest).catch(() => null)) {
  await rm(dest, { recursive: true, force: true });
}

Type guard

function isFsError(e: unknown, code: string): e is NodeJS.ErrnoException {
  return typeof e === "object" && e !== null && (e as NodeJS.ErrnoException).code === code;
}

Try / catch

try {
  await installSkillFiles(skill.name, downloadData.files, primaryDir);
} catch (err) {
  const code = (err as NodeJS.ErrnoException).code;
  if (code === "ENOENT") await mkdir(primaryDir, { recursive: true });
  if (code === "EEXIST") await rm(dest, { recursive: true, force: true });
  throw err; // let the batch logger report anything else
}

Prevention

When it happens

Trigger: ENOENT when the target skills directory or a path component does not exist; EEXIST when a file or symlink with the skill name already exists; ENOTDIR when a path component is a plain file; EMFILE/ENOSPC on descriptor or disk exhaustion; malformed file payload from a partial download.

Common situations: Dangling symlinks left by a partially removed previous install; agent skill folders moved/renamed after the CLI resolved targetDirs; full disks in CI containers; Windows path-length limits on deep skill paths.

Related errors


AI-assisted analysis of upstash/context7@5284672feb (2026-08-18). Data as JSON: /api/errors/fa724e1daf2ba0db. Report an issue: GitHub.