Troubleshooting
Common smart-link errors, their real cause, and how to check.
Creating a smart link fails 400 slug_taken even though the slug is not visible in the list
Symptom: POST /api/admin/smartlinks returns 400 slug_taken, but the slug doesn't appear in
GET /api/admin/smartlinks.
Cause: A race — a concurrent create committed the same slug between your pre-check and your commit. The database's unique constraint caught it. This is the expected behavior of that race, not a bug.
Check: Retry with a different slug, or the same slug after a short backoff
(backend/app/products/link/api/admin/smartlinks.py:362-406).
Deactivating a smart link returns 409 deactivate_confirm_required
Symptom: PATCH /api/admin/smartlinks/{id} with active: false returns 409.
Cause: Published buttons still point at this smart link — turning it off would make
/r/<slug> a live 404 for fans clicking those buttons.
Check: If that's intended, resend with confirm: true. Otherwise unlink the buttons first
(backend/app/products/link/api/admin/smartlinks.py:428-445).
ROI always shows "needs a price"
Symptom: The Performance card never lights up ROI for a link (has_cost=false), even though
it has revenue.
Cause: There's no active LinkAdSpend row for this link's key in the current window, or its
cost_model isn't one the calculator recognizes.
Check: Confirm POST /api/admin/links/cost actually saved a row, that it's active, and that
the link_key matches the row you're looking at
(backend/app/products/link/core/link/roi.py:73-94).
/validate is green but attribution still leaks
Symptom: GET /api/admin/smartlinks/{id}/validate reports no blocking issues, but revenue for
a specific country seems to be missing or merged into "other."
Cause: /validate is a resolver model — a country whose paid link exists but has an empty URL
("unminted") still resolves by falling through to the shared default. Validate has no way to see
that as a problem.
Check: Run GET /api/admin/smartlinks/{id}/routing instead — it's the more complete diagnostic
and reports the unminted link directly
(backend/app/products/link/api/admin/smartlinks.py:1429-1434). See
Validate before publishing for why
the two checks disagree.
An ad platform connection saves but the on-page pixel does not update
Symptom: You edit or create an Ad Platforms connection, but the browser pixel on the landing page stays the same.
Cause: The on-page pixel is mirrored only from a connection where platform == "meta" and
status == "active" with a non-empty pixel_id. Any other network, or a Meta connection that's
paused, never reaches the page config.
Check: Confirm the connection you edited is the active Meta one, not a different network or a
paused Meta row (backend/app/api/admin/ad_platforms_api.py:138-189).
What's next
Back to Smart links & ads.