different-ai/openwork · error
Skill create response was incomplete.
Error message
Skill create response was incomplete.
What it means
useCreateSkill POSTs a new skill and, after a 2xx response, runs parseSkillResponse on the body. If the created-skill payload can't be parsed into the expected Skill shape, the mutation throws 'Skill create response was incomplete.' The create may actually have succeeded server-side; only the response parsing failed.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/skill-data.tsx:132
export function useCreateSkill(pluginId: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (draft: SkillDraft): Promise<DenSkill> => {
const { response, payload } = await requestJson(
"/v1/config-objects",
{
method: "POST",
body: JSON.stringify(createSkillPayload(pluginId, draft)),
},
15000,
);
if (!response.ok) {
throw getRequestError(payload, response, `Failed to create skill (${response.status}).`);
}
const skill = parseSkillResponse(payload);
if (!skill) {
throw new Error("Skill create response was incomplete.");
}
return skill;
},
onSuccess: async () => {
await Promise.all([
queryClient.invalidateQueries({ queryKey: skillQueryKeys.all }),
queryClient.invalidateQueries({ queryKey: pluginQueryKeys.detail(pluginId) }),
]);
},
});
}
export function useUpdateSkill(pluginId: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (input: { skillId: string; draft: SkillDraft }): Promise<DenSkill> => {
const { response, payload } = await requestJson(View on GitHub (pinned to 2b7df46e8a)
Solutions
- Check the network response body of the create call and compare to parseSkillResponse's required fields.
- Align client parser with the current server response (update parseSkillResponse or the server to return required fields).
- Before retrying, check whether the skill was actually created (duplicate-name risk) to avoid creating it twice.
- If a proxy strips bodies, fix gateway config so JSON bodies pass through on 201.
Example fix
// before
const skill = parseSkillResponse(payload);
if (!skill) throw new Error("Skill create response was incomplete.");
// after
const skill = parseSkillResponse(payload);
if (!skill) {
console.error("create payload:", payload);
throw new Error("Skill create response was incomplete.");
} Defensive patterns
Strategy: validation
Validate before calling
function isCreatableSkillInput(v: unknown): boolean {
return isRecord(v) && typeof v.name === "string" && v.name.trim().length > 0;
} Type guard
function isSkillResponse(v: unknown): v is Skill {
return isRecord(v) && typeof v.id === "string";
} Try / catch
try {
await createSkill(input);
} catch (e) {
if (e instanceof Error && e.message === "Skill create response was incomplete.") {
// verify whether the skill was actually created before retrying (avoid duplicates)
await queryClient.invalidateQueries({ queryKey: skillQueryKeys.all });
} else throw e;
} Prevention
- After a parse failure, invalidate the list query before any retry to avoid duplicate creates
- Add integration tests asserting the create-response shape
- Keep server and client deployed in lockstep
When it happens
Trigger: POST /skills (plugin-scoped) returns ok but the body lacks fields parseSkillResponse requires (e.g. missing id, name, or steps array), or body is not a JSON record.
Common situations: API version drift after a server deploy changes the create-response shape; a gateway returns an empty 201 body; client parse expectations updated without matching server release.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Skill update response was incomplete.
- invalid_cloud_plugin
- Skill detail response was incomplete.
- The Workflow response was invalid.
- The snapshot response was invalid.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/0d11a3f8f0d4f74e.
Report an issue: GitHub.