{"record":{"id":"27694f5f76dbc249","repo":"paperclipai/paperclip","slug":"catalog-skill-reference-is-required","errorCode":null,"errorMessage":"Catalog skill reference is required.","messagePattern":"Catalog skill reference is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/skills.ts","lineNumber":596,"sourceCode":"  return (await ctx.api.get<CompanySkillListItem[]>(`/api/companies/${ctx.companyId}/skills`)) ?? [];\n}\n\nasync function listCatalogSkills(\n  ctx: ResolvedClientContext,\n  opts: CatalogBrowseOptions,\n): Promise<CatalogSkill[]> {\n  const params = new URLSearchParams();\n  appendQueryParam(params, \"kind\", opts.kind);\n  appendQueryParam(params, \"category\", opts.category);\n  appendQueryParam(params, \"q\", opts.query);\n  const query = params.toString();\n  return (await ctx.api.get<CatalogSkill[]>(`/api/skills/catalog${query ? `?${query}` : \"\"}`)) ?? [];\n}\n\nasync function getCatalogSkill(ctx: ResolvedClientContext, catalogRef: string): Promise<CatalogSkill> {\n  const ref = catalogRef.trim();\n  if (!ref) {\n    throw new Error(\"Catalog skill reference is required.\");\n  }\n  const detail = await ctx.api.get<CatalogSkill>(`/api/skills/catalog/ref?ref=${encodeURIComponent(ref)}`);\n  if (!detail) {\n    throw new Error(`Catalog skill not found: ${catalogRef}`);\n  }\n  return detail;\n}\n\nexport function resolveCompanySkillReference(\n  skills: CompanySkillReferenceTarget[],\n  reference: string,\n): CompanySkillReferenceTarget {\n  const trimmed = reference.trim();\n  if (!trimmed) {\n    throw new Error(\"Skill reference is required.\");\n  }\n\n  const byId = skills.find((skill) => skill.id === trimmed);","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/skills.ts#L578-L614","documentation":"Thrown by getCatalogSkill() in the skills CLI client when the catalog skill reference argument is empty after trimming. The function guards its call to GET /api/skills/catalog/ref?ref=... because an empty ref would produce a meaningless API request. It is a pure client-side input guard, reached before any network call.","triggerScenarios":"Running `paperclipai skills inspect <catalogRef>` (or any path calling getCatalogSkill) with a reference that is an empty string or only whitespace, e.g. `paperclipai skills inspect \"   \"`. The commander `<catalogRef>` argument is required, so this only fires when the value is present-but-blank.","commonSituations":"Shell expansion that yields an empty variable (e.g. `paperclipai skills inspect \"$MY_REF\"` where MY_REF is unset/blank), script loops passing untrimmed input, or copy-paste mistakes.","solutions":["Pass a non-empty catalog skill ID, key, or unique slug to `skills inspect`.","If the ref comes from a variable, validate it is non-empty before invoking the CLI.","List valid refs first with `paperclipai skills browse` and pick one."],"exampleFix":"// before\nconst ref = process.env.SKILL_REF ?? \"\";\nawait run([\"skills\", \"inspect\", ref]);\n// after\nconst ref = (process.env.SKILL_REF ?? \"\").trim();\nif (!ref) throw new Error(\"SKILL_REF must be set\");\nawait run([\"skills\", \"inspect\", ref]);","handlingStrategy":"validation","validationCode":"const ref = (catalogRef ?? \"\").trim();\nif (!ref) {\n  throw new Error(\"Provide a non-empty catalog skill id, key, or slug.\");\n}\nawait cli([\"skills\", \"inspect\", ref]);","typeGuard":"function isValidCatalogRef(ref: string | undefined): ref is string {\n  return typeof ref === \"string\" && ref.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always trim and check ref length before passing to the CLI.","Source refs from `skills browse` output rather than hand-typing.","In scripts, fail fast on empty environment variables before expansion."],"tags":["cli","validation","skills","catalog","input"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}