sY8xsvmkqD, the one case in the
share deep-link matrix that mounted its route but failed to load.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.
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.
…-26SEP-H0 → error screen…-26SEP → loads correctly| Request | Result |
|---|---|
GET /predictions/v2/event/dflownative/KXFEDDECISION-26SEPevent ticker | 200 — "Fed decision in Sep 2026?" |
GET /predictions/v2/event/kalshi/KXFEDDECISION-26SEPevent ticker | 200 — "Fed decision in Sep 2026?" |
GET /predictions/v2/event/dflownative/KXFEDDECISION-26SEP-H0market ticker (what the fallback produces) | 404 — Event with id "…-H0" not found |
GET /predictions/v2/event/kalshi/KXFEDDECISION-26SEP-H0market ticker | 404 — Event with id "…-H0" not found |
Three plausible recovery routes were checked. None of them work.
| Candidate fix | Why 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.
The live blast radius is small, but the only thing holding it closed is a truthiness check.
buildPredictionShareRequest, and it always
emits kind: "existing_position" with predictions/event/<eventTicker> attached.
The new_position prediction share used in this test is not something the app produces today.eventTicker is a required z.string() in the positions schema, so it is
normally present.eventTicker ? `predictions/event/…` : undefined.
An empty string passes schema validation, is falsy, silently drops the path, and mints a dead
link — permanently, because records are immutable.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.
eventTicker is missing or empty,
a prediction share should not be created at all. A share that opens an error screen is worse than a share
that never existed, and immutability means there is no second chance.withDeepLinkPathFallback. It advertises a safety net
that cannot work, and its v1/predictions/<ticker> output routes nowhere.eventTicker field
alongside ticker is the only change that makes server-side derivation correct — and it would
let the service stop guessing.{
"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
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).