paperclipai/paperclip · error · Error
No update status returned for skill ${skill.key}.
Error message
No update status returned for skill ${skill.key}. What it means
Thrown by checkCompanySkills() when GET /api/companies/{companyId}/skills/{skillId}/update-status returns null/undefined for an installed skill. The CLI expects a CompanySkillUpdateStatus object; a null body is treated as a contract violation rather than silently skipping the row.
Source
Thrown at cli/src/commands/client/skills.ts:649
ctx: ResolvedClientContext,
reference: string,
): Promise<CompanySkillReferenceTarget> {
return resolveCompanySkillReference(await listCompanySkills(ctx), reference);
}
async function checkCompanySkills(
ctx: ResolvedClientContext,
skillRef: string | undefined,
): Promise<CompanySkillCheckRow[]> {
const skills = await listCompanySkills(ctx);
const selected = skillRef ? [resolveCompanySkillReference(skills, skillRef)] : skills;
const rows: CompanySkillCheckRow[] = [];
for (const skill of selected) {
const status = await ctx.api.get<CompanySkillUpdateStatus>(
`/api/companies/${ctx.companyId}/skills/${encodeURIComponent(skill.id)}/update-status`,
);
if (!status) {
throw new Error(`No update status returned for skill ${skill.key}.`);
}
rows.push({ skill: toSkillReferenceTarget(skill), status });
}
return rows;
}
async function updateOneCompanySkill(
ctx: ResolvedClientContext,
skillRef: string,
opts: SkillUpdateOptions = {},
): Promise<CompanySkillUpdateRow> {
const skill = await resolveCompanySkill(ctx, skillRef);
const updated = await ctx.api.post<CompanySkill>(
`/api/companies/${ctx.companyId}/skills/${encodeURIComponent(skill.id)}/install-update`,
{ force: opts.force || undefined },
);
return {
skillRef,View on GitHub (pinned to 67001ec6eb)
Solutions
- Confirm CLI and server versions match (`paperclipai --version`, server /api/health).
- Retry `skills check` after refreshing the company context.
- If persistent, inspect the raw response with `curl /api/companies/{id}/skills/{sid}/update-status` to see whether the server or transport drops the body.
Example fix
# before paperclipai skills check my-skill # diagnose curl -sS "$API/api/companies/$CID/skills/$SID/update-status" -H "authorization: Bearer $TOKEN" | jq .
Defensive patterns
Strategy: try-catch
Type guard
function isUpdateStatus(v: unknown): v is CompanySkillUpdateStatus {
return v != null && typeof v === "object";
} Try / catch
try {
await run(["skills", "check", ref]);
} catch (err) {
if (err instanceof Error && /No update status returned/.test(err.message)) {
console.error("Server returned no status. Check CLI/server version alignment.");
process.exit(2);
}
throw err;
} Prevention
- Keep CLI and server versions in sync.
- Smoke-test /api/health and the update-status route after upgrades.
- Treat null-body responses as a version/transport defect to investigate.
When it happens
Trigger: `paperclipai skills check [skillRef]` (or the per-skill update-status fetch) where the server returns an empty 2xx response, the route is missing in the deployed API version, or a proxy strips the body.
Common situations: Version skew between an older/newer CLI and server, a misbehaving gateway that returns 200 with no body, or the skill id resolving to a row the server no longer recognizes mid-flight.
Related errors
- No audit result returned for skill ${skill.key}.
- Catalog skill not found: ${catalogRef}
- Approval request failed.
- Could not locate local Paperclip skills directory. Expected
- Failed to create agent token
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/fdc73fc3f4a8b428.
Report an issue: GitHub.