---
name: Missing OR wrong team_map abbr silently drops Kalshi AWAY/HOME columns
description: When a team is missing from team_map.json OR has the wrong kalshi abbr, the event title-matches but the per-market ticker 404s, silently blanking one column's market data
type: feedback
---

If a Kalshi live snapshot shows `Kalshi=?A` (or `?H`) for many minutes despite the user pointing at an obvious orderbook on Kalshi, **first check whether both team names exist in `E:\soccer\team_map.json`**.

**Why:** Discovered 2026-05-28 on Casa Pia vs Torreense (P1). Torreense was missing from team_map. `get_abr('Torreense')` returned `None`. `kalshi_live.get_all_prices()` (line ~73) title-matches the event correctly via the fallback at lines 96-106 — but the per-market loop at line ~112 then builds `f"{event}-{None}"`, which 404s. Result: HOME column populated, AWAY column blank, real +8.1% CLV signal silently missed. Fix was a one-line addition to team_map.json: `"Torreense": { "div": "P1", "fdco": "Torreense", "kalshi": "TOR" }`.

**Second variant — WRONG abbr, not missing (2026-05-29, Monza vs Catanzaro, I2/KXSERIEBGAME):** Same blank-away symptom, but `get_abr` returned a non-None value that was simply *wrong*. team_map had Catanzaro→`CAT`, but Kalshi abbreviates it `USC` (full name *US Catanzaro* — Kalshi uses the club-prefix form). Event resolved via title search so HOME/DRAW populated, but the away leg fetched `...MONUSC-CAT` → 404 → blank away all game. Fix: Catanzaro `kalshi` `CAT`→`USC`. **Lesson: a non-None abbr does NOT clear this bug** — when one column is persistently blank, verify the abbr against an actual settled ticker (`/markets?series_ticker=…&status=settled`), don't just check that it's non-None.

**Third variant — ACCENTED name, now FIXED at the framework level (2026-06-06, Castellón vs Almería, SP2/KXLALIGA2GAME):** *Both* Kalshi columns (and clv) were NaN on every snapshot despite an open market with ~$1,964 volume. Cause: API-Football sends accented names (`Castellón`/`Almería`) but team_map keys + alias index were plain ASCII (`Castellon`/`Almeria`) and `maps._lookup` did `name.lower()` with NO accent-folding → `get_abr` returned `None` for BOTH sides → `find_event_by_abrs` bailed immediately and the title fallback also failed (`'castellón' not in 'castellon vs almeria'`) → `get_all_prices` returned None → NaN. **Fix (durable, fixes the whole class): added `maps._fold()` (NFKD normalize + strip combining marks + lower) and applied it both when building `_alias_idx` and in `_lookup`.** Verified accent-folding adds ZERO new cross-team collisions vs the prior `.lower()` (the 5 pre-existing ones — Bradford/Bradford City, Falkirk/Falkirk FC, Inter Miami/Miami FC — are identical before/after). So you should no longer need per-team accented aliases; if an accented team still misses, it's the missing/wrong-abbr variant, not accents.

**How to apply:**
- Symptom: persistent `Kalshi=?A` or `?H` while the other side shows a price, AND a Kalshi market clearly exists.
- If BOTH sides are blank on a team with an accent in its name, it WAS the accent-fold bug — now fixed in maps.py; just confirm maps has `_fold` and that live_monitor was restarted after the fix.
- Diagnosis: `python -c "import maps; print(maps.kalshi_abr('TeamName'))"` — if None, missing-entry variant. If non-None, query `/markets?series_ticker=<SERIES>&status=settled` and compare the real ticker's trailing abbr against what we store (the wrong-abbr variant). Kalshi often uses club-prefix forms (US Catanzaro→USC).
- Fix: add or correct the team in `team_map.json` matching the existing league pattern (look up the Kalshi ticker from a recent settled market).
- `maps.py` loads `team_map.json` once at module import, so **live_monitor must be restarted** to pick up new entries. NOTE: live_monitor's `maps.changed()`/`maps.reload()` hot-reload only re-reads the JSON DATA files — it does NOT re-import maps.py CODE, so any fix to maps.py itself (like `_fold`) requires a full process restart.
- Restart pattern (Windows, must survive parent shell exit): `subprocess.Popen([python, '-u', 'live_monitor.py'], cwd=r'E:\soccer', stdin=DEVNULL, stdout=log, stderr=STDOUT, creationflags=DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW, close_fds=True)`.
