paperclipai/paperclip · error · Error
Skill reference is required.
Error message
Skill reference is required.
What it means
Thrown by resolveCompanySkillReference() when the reference string is empty after trimming. This shared resolver backs every company-skill operation (show, files, update, reset, remove, audit, agent sync). It guards up front because all downstream lookups (by id, key, slug) would otherwise be no-ops.
Source
Thrown at cli/src/commands/client/skills.ts:611
async function getCatalogSkill(ctx: ResolvedClientContext, catalogRef: string): Promise<CatalogSkill> {
const ref = catalogRef.trim();
if (!ref) {
throw new Error("Catalog skill reference is required.");
}
const detail = await ctx.api.get<CatalogSkill>(`/api/skills/catalog/ref?ref=${encodeURIComponent(ref)}`);
if (!detail) {
throw new Error(`Catalog skill not found: ${catalogRef}`);
}
return detail;
}
export function resolveCompanySkillReference(
skills: CompanySkillReferenceTarget[],
reference: string,
): CompanySkillReferenceTarget {
const trimmed = reference.trim();
if (!trimmed) {
throw new Error("Skill reference is required.");
}
const byId = skills.find((skill) => skill.id === trimmed);
if (byId) return byId;
const byKey = skills.find((skill) => skill.key === trimmed);
if (byKey) return byKey;
const normalizedSlug = normalizeSkillSlug(trimmed);
const bySlug = skills.filter((skill) => skill.slug === normalizedSlug);
if (bySlug.length === 1 && bySlug[0]) return bySlug[0];
if (bySlug.length > 1) {
throw new Error(`Ambiguous skill slug "${trimmed}". Use a skill ID or key instead.`);
}
throw new Error(`Skill not found: ${reference}`);
}
View on GitHub (pinned to 67001ec6eb)
Solutions
- Supply a non-empty company skill ID, key, or unique slug as the positional argument.
- If resolving dynamically, list company skills first (`skills list`) and feed a concrete id/key.
- Trim and validate the value in your wrapper script before calling the CLI.
Example fix
// before
await run(["skills", "show", refFromUser]);
// after
const ref = (refFromUser ?? "").trim();
if (!ref) throw new Error("skillRef is required");
await run(["skills", "show", ref]); Defensive patterns
Strategy: validation
Validate before calling
const ref = (skillRef ?? "").trim();
if (!ref) {
throw new Error("skillRef is required for this command");
} Type guard
function isNonEmptyRef(ref: string | undefined): ref is string {
return typeof ref === "string" && ref.trim().length > 0;
} Prevention
- Validate positional args in your wrapper before dispatching.
- Never pass unchecked user input straight to skills subcommands.
- Use the same trim-and-check helper across all skills commands.
When it happens
Trigger: Any company-scoped skills command with a blank positional `<skillRef>`: `paperclipai skills show ""`, `skills remove " "`, or an agent sync where the resolver is invoked with empty input.
Common situations: Unset environment variable expanded into the positional arg, programmatic callers forgetting to supply a ref, or trailing whitespace from a list-parse step.
Related errors
- Catalog skill reference is required.
- Prompt text is required
- Agent reference is required
- Invalid --include value. Use one or more of: company,agents,
- Invalid --kind value. Use: all, secret, plain
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/de0ef3252b53a4e8.
Report an issue: GitHub.