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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions