{"record":{"id":"f19bc5210d86158c","repo":"Significant-Gravitas/AutoGPT","slug":"name-is-required","errorCode":null,"errorMessage":"name is required","messagePattern":"name is required","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"autogpt_platform/backend/backend/api/features/v1.py","lineNumber":2781,"sourceCode":"    summary=\"Delete a user-distilled copilot skill\",\n    operation_id=\"deleteCopilotSkill\",\n    tags=[\"skills\"],\n    dependencies=[Security(requires_user)],\n)\nasync def delete_copilot_skill(\n    user_id: Annotated[str, Security(get_user_id)],\n    name: str = Path(..., description=\"Slug of the skill to delete\"),\n) -> dict[str, str]:\n    \"\"\"Delete a user-distilled skill by slug.\n\n    Built-in defaults are not user-deletable — attempting to delete one\n    returns 400.  Missing skills return 404 so the UI can reconcile a\n    stale list.\n    \"\"\"\n    try:\n        slug = await delete_user_skill(user_id, name)\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc))\n    except BuiltInSkillError as exc:\n        raise HTTPException(status_code=400, detail=str(exc))\n    except SkillNotFoundError as exc:\n        raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail=str(exc))\n    return {\"name\": slug}\n\n\n########################################################\n#####################  API KEY ##############################\n########################################################\n\n\n@v1_router.post(\n    \"/api-keys\",\n    summary=\"Create new API key\",\n    tags=[\"api-keys\"],\n    dependencies=[Security(requires_user)],\n)","sourceCodeStart":2763,"sourceCodeEnd":2799,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/v1.py#L2763-L2799","documentation":"Skill-delete endpoint returns 400 when `delete_user_skill(user_id, name)` raises ValueError, with the message passed through verbatim — 'name is required' fires when the provided skill name/slug is empty after normalization (e.g. path segment is empty or whitespace-only). This is a request-shape problem, not a missing skill (that is SkillNotFoundError → 404).","triggerScenarios":"DELETE /skills/{name} where name is empty, only whitespace, or a route constructed with a missing path segment producing an empty string before validation.","commonSituations":"Frontend building the URL from an undefined/null field and sending '/skills/%20' or '/skills/'; hand-crafted API calls trimming the segment away; test fixtures passing an empty slug.","solutions":["Always derive the slug from a non-empty selected skill object and guard before calling.","Normalize with trim().toLowerCase() and skip the request when the result is empty.","Note that FastAPI Path params can't normally be empty — so also check for double slashes or encoded emptiness (%20) in the URL."],"exampleFix":"// before\nawait fetch(`/api/skills/${name}`, {method:'DELETE'});\n// after\nconst slug = name?.trim().toLowerCase();\nif (!slug) throw new Error('Select a skill to delete');\nawait fetch(`/api/skills/${encodeURIComponent(slug)}`, {method:'DELETE'});","handlingStrategy":"validation","validationCode":"const slug = name?.trim().toLowerCase();\nif (!slug) { show('Select a skill to delete'); return; }\nawait api.deleteSkill(slug);","typeGuard":"function isNonEmptySlug(name: unknown): name is string {\n  return typeof name === 'string' && name.trim().length > 0;\n}","tryCatchPattern":"try {\n  await api.deleteSkill(slug);\n} catch (e) {\n  if (e.status === 400 && /name is required/i.test(e.detail)) { fixCaller(); return; }\n  throw e;\n}","preventionTips":["Never build delete URLs from possibly-undefined fields.","Guard empty/whitespace slugs client-side.","Encode the path segment with encodeURIComponent."],"tags":["http-400","skills","input-validation","slug"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}