TEASEDocs
ProductsLinkQR codes

Troubleshooting

Known QR code failure modes, their cause, and how to confirm it.

A saved QR code 500s on download or render

Symptom: A code that used to render fine now 500s from GET /api/admin/qr/{domain}/{qr_id}/image.svg.

Cause: The design references an icon file (a logo: "icon:<name>", or the tease brand mark) that was on disk when the design was saved but has since been removed. Validation checks the file exists at save time — it doesn't re-check at render time — so the stored config still points at a name or path that no longer resolves.

Check: Look at the code's stored design_json for a "logo": "icon:<name>" value, then confirm <name>.svg still exists under the icons static directory (backend/app/products/link/core/qr/design.py:292-326 reads it, list_icon_names() at line 74 lists what currently exists). If the icon is gone, either restore the file or PATCH the code to a different logo/preset — see Design a QR code.

Domain rotation or rollback is blocked with no_qr_codes

Symptom: Rotating a domain to a new hostname, or rolling back a migration, fails with a block naming QR codes.

Cause: At least one QrCode row exists on the address being moved. This is by design, not a bug: a QR code is printed onto a physical carrier out in the world, and there's no way to auto-migrate ink on paper — silently moving or invalidating the domain underneath a printed code would 404 or mislabel every scan of it from that point on.

Check: domain_qr_count(session, old, new) > 0 (backend/app/products/link/core/domain_carrier_guard.py:105-135) is what the rotation guard calls. Before rotating, either wait until the printed carriers are fully retired, or use Rename or disable a QR code to move each code's scan path onto the new address deliberately — there is no bulk auto-migration.

What's next

Back to QR codes for the full task list.

On this page