TEASEDocs
ProductsLinkSmart links & ads

Troubleshooting

Common smart-link errors, their real cause, and how to check.

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).

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.

On this page