abi/screenshot-to-code · error · HTTPException

Design system not found

Error message

Design system not found

What it means

Raised by the update handler PUT /api/design-systems/{design_system_id} (404) when no stored design system has a matching id. The handler scans the in-memory list by id and falls through to this exception when the loop finds nothing — the id may be wrong, or the entry was deleted between read and write.

Source

Thrown at backend/routes/design_systems.py:149

        if design_system.id != design_system_id:
            continue

        updated = design_system.model_copy(
            update={
                "name": normalize_name(request.name)
                if request.name is not None
                else design_system.name,
                "content": request.content
                if request.content is not None
                else design_system.content,
                "updatedAt": utc_timestamp(),
            }
        )
        design_systems[index] = updated
        write_design_systems(design_systems)
        return updated

    raise HTTPException(status_code=404, detail="Design system not found")


@router.delete("/api/design-systems/{design_system_id}")
async def delete_design_system(design_system_id: str) -> Response:
    design_systems = read_design_systems()
    remaining = [
        design_system
        for design_system in design_systems
        if design_system.id != design_system_id
    ]

    if len(remaining) == len(design_systems):
        raise HTTPException(status_code=404, detail="Design system not found")

    write_design_systems(remaining)
    return Response(status_code=204)

View on GitHub (pinned to d026163f58)

Solutions

  1. GET /api/design-systems and use an id from the current list.
  2. If the system is missing, create it with POST instead of PUT.
  3. Confirm the backend points at the same SCREENSHOT_TO_CODE_DATA_DIR used when the id was issued.

Example fix

# before
requests.put(url + f"/api/design-systems/{ds_id}", json={"name": "new"})  # 404

# after
ids = {d["id"] for d in requests.get(url + "/api/design-systems").json()}
if ds_id not in ids:
    resp = requests.post(url + "/api/design-systems", json=payload)
else:
    resp = requests.put(url + f"/api/design-systems/{ds_id}", json=payload)
Defensive patterns

Strategy: validation

Validate before calling

systems = requests.get(url + "/api/design-systems").json()
known_ids = {s["id"] for s in systems}
if ds_id not in known_ids:
    ds_id = None  # create instead of update
verb, path = (("PUT", f"/api/design-systems/{ds_id}") if ds_id
              else ("POST", "/api/design-systems"))

Type guard

def design_system_exists(ds_id: str, systems: list[dict]) -> bool:
    return any(s.get("id") == ds_id for s in systems)

Try / catch

resp = requests.put(url + f"/api/design-systems/{ds_id}", json=payload)
if resp.status_code == 404:
    resp = requests.post(url + "/api/design-systems", json=payload)  # upsert
resp.raise_for_status()

Prevention

When it happens

Trigger: PUT /api/design-systems/{id} with an id that is not in design-systems.json: stale id after a delete, typo, or a fresh data directory that no longer holds the entry.

Common situations: UI keeps an edit dialog open while another tab deletes the system; switched data dir / machine so the file has different ids; copied id with whitespace.

Related errors


AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14). Data as JSON: /api/errors/0914ac5a439d4edd. Report an issue: GitHub.