Skip to content

Skill archive download failures return 200 JSON instead of an HTTP error #9212

Description

@VectorPeak

Problem

The skill archive download endpoints return a ZIP file on success, but failed archive preparation currently returns a JSON error envelope with HTTP 200.

Affected endpoints:

  • GET /api/v1/skills/archive?skill_name=...
  • GET /api/v1/skills/{skill_name}/archive
  • legacy GET /api/skills/download?name=...

This is confusing for callers that treat these endpoints as binary downloads. The dashboard calls the v1 query endpoint with responseType: 'blob', wraps the response as application/zip, and saves it as <skill>.zip. If the backend returns a 200 JSON error body, the browser can save an error payload as a fake ZIP archive.

Reproduction sketch

  1. Request a skill archive for a local skill that cannot be exported, such as a missing skill or a plugin-provided/sandbox-only skill.
  2. Backend SkillsService.prepare_skill_archive() raises SkillsServiceError.
  3. _download_skill() catches the exception and returns error(str(exc)).
  4. FastAPI serializes that dict as HTTP 200 JSON.
  5. Blob/ZIP callers treat the response as a successful archive download.

Expected behavior

Failed skill archive downloads should return a non-2xx HTTP error while preserving the existing JSON error shape.

Actual behavior

Failed skill archive downloads can return HTTP 200 with a JSON error body.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions