Prediction share deep links: the payload-derived fallback is structurally broken

Investigation of share record sY8xsvmkqD, the one case in the share deep-link matrix that mounted its route but failed to load.
A prediction share created without an explicit deepLinkPath mints a permanently dead link. The share payload carries the market ticker; prediction event detail routes by event ticker. Nothing on the server or in the app can convert one into the other, so every fallback path — the share service's own derivation and the mobile client's — produces a link that opens an error screen. Share records are immutable, so the link can never be repaired.

What happened

The record was created with no deepLinkPath in the request. The share service filled one in by itself, derived from the payload's ticker:

POST /share
{ "payload": { "kind": "new_position", "market": "prediction",
               "ticker": "KXFEDDECISION-26SEP-H0", ... } }     // no deepLinkPath sent

GET /share/sY8xsvmkqD
  "deepLinkPath": "predictions/event/KXFEDDECISION-26SEP-H0"   // service derived this

That path matches the resolver's allowed shape, so resolvePredictionDeepLink honours it verbatim and the app navigates. The route mounts correctly — and then the screen's data fetch 404s.

phantom://share/sY8xsvmkqD
  → GET /share/sY8xsvmkqD → stored path predictions/event/KXFEDDECISION-26SEP-H0
  → phantom://predictions/event/KXFEDDECISION-26SEP-H0?share_id=sY8xsvmkqD
  → route __root › (predictions) › predictionEventDetail  mounts
  → GET /predictions/v2/event/dflownative/KXFEDDECISION-26SEP-H0 → 404
  → "Something went wrong / Retry"
Fallback path
market ticker …-26SEP-H0 → error screen
Client-supplied path
event ticker …-26SEP → loads correctly

The API confirms the ticker distinction

RequestResult
GET /predictions/v2/event/dflownative/KXFEDDECISION-26SEP
event ticker
200 — "Fed decision in Sep 2026?"
GET /predictions/v2/event/kalshi/KXFEDDECISION-26SEP
event ticker
200 — "Fed decision in Sep 2026?"
GET /predictions/v2/event/dflownative/KXFEDDECISION-26SEP-H0
market ticker (what the fallback produces)
404 — Event with id "…-H0" not found
GET /predictions/v2/event/kalshi/KXFEDDECISION-26SEP-H0
market ticker
404 — Event with id "…-H0" not found

Why it cannot be repaired downstream

Three plausible recovery routes were checked. None of them work.

Candidate fixWhy it fails
predictions/market/<ticker> route Alias only. In phantomDeepLinkPredictions.ts, case "event": and case "market": share one branch. It renames the segment; it performs no market → event lookup.
Look the event up from the market Field isn't served. GET /predictions/v2/market/kalshi/KXFEDDECISION-26SEP-H0 returns 200 but its body carries no eventTicker / eventId — only id, title, subtitle, status, outcomes, …. (The dflownative variant 400s.)
Strip the trailing -XX segment Not safe. Event tickers contain hyphens themselves — e.g. the event KXBTCMAXMON-BTC-26AUG31. There is no lexical rule separating event from market.

The event ticker exists in exactly one place: the client's position.platformData.eventTicker. Any derivation that starts from the share payload is working from information that was already thrown away.

Current exposure

The live blast radius is small, but the only thing holding it closed is a truthiness check.

A second dead path found along the way

withDeepLinkPathFallback derives v1/predictions/<ticker> for prediction payloads. That shape is doubly useless: the resolver's PREDICTION_EVENT_PATH regex rejects it (so it is ignored in favour of the market-ticker derivation), and it does not route at all — firing phantom://v1/predictions/KXFEDDECISION-26SEP at the app leaves it on the home tab, verified live.

Recommendation

Record under test

{
    "shareId": "sY8xsvmkqD",
    "v": 2,
    "payload": {
        "chanceMultiplier": "1.42",
        "kind": "new_position",
        "market": "prediction",
        "outcome": "Fed maintains rate",
        "priceSeries": [
            "0.40000000",
            "0.42000000",
            "0.44000000",
            "0.46000000",
            "0.48000000",
            "0.50000000",
            "0.52000000",
            "0.54000000",
            "0.56000000",
            "0.58000000",
            "0.60000000",
            "0.62000000"
        ],
        "ticker": "KXFEDDECISION-26SEP-H0",
        "valueUsd": "50.00"
    },
    "sharer": {
        "avatarUrl": "https://api.phantom.app/image-proxy/?image=https%3A%2F%2Flh3.googleusercontent.com%2F9gT6FdrAgl-mlcrvvvsmpu4QGpwkvkUhtv92ARzHyLhS3unLQYlFJtCrNZX3MAElrcyKUYjftIA93td8B-XA0u5Fs3EreBHzFxY%3Ds250-k",
        "username": "mistystarmie"
    },
    "deepLinkPath": "predictions/event/KXFEDDECISION-26SEP-H0",
    "createdAt": "2026-08-14T16:00:46.042Z",
    "display": {
        "headerTitle": "Share Position",
        "title": "KXFEDDECISION-26SEP-H0",
        "subtitle": "Fed maintains rate",
        "badge": {
            "text": "Fed maintains rate",
            "color": "positive"
        },
        "icon": {
            "fallbackText": "K"
        },
        "headline": {
            "value": "$50.00",
            "amountUsd": "5
Method: real share records created against api.phantom.app/share, resolved by the shipping resolveShareTarget, fired at a booted iOS simulator as phantom://share/<id>, with the resulting route read out of the app's live React Navigation state and a screenshot captured. Part of the wider share position deep link matrix (34 records; this was the one route-level pass that failed on content).