heygen-com/hyperframes · error · Error

Skill(s) still missing after install: ${absent.join(", ")}

Error message

Skill(s) still missing after install: ${absent.join(", ")}

What it means

Thrown (or warned) by verifyInstalled after an install attempt when some requested skills still aren't on disk. presentSkills is re-evaluated against the names list; any name not present is 'absent'. Strictness mirrors the caller — strict (check/update CI contract, router trigger-time guarantee) throws loud; non-strict (init) only warns and proceeds.

Source

Thrown at packages/cli/src/commands/skills.ts:411

}

/**
 * The presence half of the guarantee, after an install claims success: every
 * name must now exist on disk. Catches the "install exited 0 but delivered
 * nothing" failure mode, which would otherwise surface much later as a
 * workflow reading skill files that aren't there.
 *
 * Strictness mirrors the caller's tolerance: a strict run (the `check ||
 * update` CI contract, the router's trigger-time guarantee) throws so the
 * failure is loud; a non-strict run (init) only warns and proceeds, since a
 * skills hiccup must never break scaffolding.
 */
function verifyInstalled(names: readonly string[], opts: { strict: boolean; cwd?: string }): void {
  const present = new Set(presentSkills(names, { cwd: opts.cwd }));
  const absent = names.filter((name) => !present.has(name));
  if (absent.length === 0) return;
  const message = `Skill(s) still missing after install: ${absent.join(", ")}`;
  if (opts.strict) throw new Error(message);
  clack.log.warn(c.warn(message));
}

/**
 * Offline degradation for updateSkills: the manifest is unreachable, so
 * freshness is unknowable. What can still be honored is the PRESENCE half of
 * the guarantee, extended to the pinned FALLBACK_CORE_SKILLS list so the
 * router / preamble promise ("this workflow plus the core set it depends on")
 * doesn't silently shrink to just the named skill on degraded networks —
 * raw.githubusercontent.com blocked while `git clone` works is a real
 * corporate-proxy shape, which is exactly when the blind install below can
 * still succeed.
 *
 *   - Named run (`update <workflow>`): presence-check requested + fallback
 *     core, blind-install whatever is absent (a truly dead network fails the
 *     clone fast, and `strict` decides how loudly). Stale-but-present
 *     proceeds — blocking a build on a network hiccup is worse than running
 *     one release behind.

View on GitHub (pinned to c2996c8626)

Solutions

  1. Re-run the install online: `npx hyperframes skills update <name>`
  2. Check disk space and write permissions in the target .agents/skills dir
  3. Inspect the install log for the failing skill and retry just that one
  4. If non-strict, the warning is non-fatal — proceed or install manually
Defensive patterns

Strategy: retry

Validate before calling

function presentSkills(names: string[], opts: { cwd?: string }): string[] {
  // returns the subset of `names` whose directories exist under .agents/skills
  return names.filter((n) => existsSync(join(opts.cwd ?? ".", ".agents/skills", n)));
}

Try / catch

try {
  verifyInstalled(names, { strict: true });
} catch (e) {
  if (e.message.includes("still missing after install")) {
    // re-run the install online, then verify again
  }
  throw e;
}

Prevention

When it happens

Trigger: verifyInstalled(names, {strict}) computes present = presentSkills(names) and filters absent names; if absent is non-empty and opts.strict is true the message is thrown at skills.ts:411.

Common situations: The `npx skills add` clone/copy step partially failed (network hiccup, disk full); a skill directory was deleted after install; permissions blocked writing the skill files; a manifest pointed at a path that no longer exists in the repo.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/8c7f22c3df2887e4. Report an issue: GitHub.