mvanhorn/last30days-skill · warning · KeyError
Polymarket event is closed, unavailable, or malformed
Error message
Polymarket event is closed, unavailable, or malformed
What it means
KeyError raised when the Gamma event was found but parse_polymarket_response produced no items from it. The parse uses include_closed=not has_active, so this fires when the event exists yet contains no markets matching the active/closed filter - i.e. it is closed, unavailable, or its markets array is malformed.
Source
Thrown at skills/last30days/scripts/lib/polymarket.py:1017
event = None
if not isinstance(event, dict):
raise KeyError("Polymarket event was not found")
# Mixed events: an active event can carry resolved child markets whose
# high volume would win the parse and swap the outcome labels. Only fall
# back to closed markets when nothing is active (fully resolved event -
# the stale-odds transition verification exists to catch).
markets = event.get("markets") or []
has_active = any(
isinstance(m, dict) and m.get("active", True) and not m.get("closed", False)
for m in markets
)
parsed = parse_polymarket_response(
{"events": [event]},
include_all_outcomes=True,
include_closed=not has_active,
)
if not parsed:
raise KeyError("Polymarket event is closed, unavailable, or malformed")
refreshed = parsed[0]
values: dict[str, Any] = {}
outcome_pairs = refreshed.get("outcome_prices") or []
outcome_totals: dict[str, int] = {}
for name, _price in outcome_pairs:
normalized = str(name).casefold()
outcome_totals[normalized] = outcome_totals.get(normalized, 0) + 1
outcome_counts: dict[str, int] = {}
for name, price in outcome_pairs:
normalized = str(name).casefold()
occurrence = outcome_counts.get(normalized, 0)
outcome_counts[normalized] = occurrence + 1
key = f"{name}\x1f{occurrence}" if outcome_totals[normalized] > 1 else str(name)
values[key] = price
if refreshed.get("end_date") is not None:
values["end_date"] = refreshed["end_date"]
if datum_key == "end_date":View on GitHub (pinned to c7460f6114)
Solutions
- Catch KeyError and present the last known value with an 'event closed' note instead of failing the whole verification pass
- Skip re-verification for events whose updatedAt is old relative to the original fetch
- For genuinely closed events, route users to the resolution outcome rather than odds
Example fix
# before
refreshed = refetch_datum(item, "Yes")
# after
try:
refreshed = refetch_datum(item, "Yes")
except KeyError:
return {"value": cached_value, "stale": True, "note": "event closed or unavailable"} Defensive patterns
Strategy: fallback
Try / catch
try:
datum = refetch_datum(item, key)
except KeyError as e:
if "closed, unavailable, or malformed" in str(e):
datum = {"value": cached_value, "stale": True} Prevention
- Check event['closed'] / market resolution status before requesting an odds refresh
- Present last-known values with a staleness note for resolved events
- Compare event['updatedAt'] to the original fetch time to skip pointless refreshes
When it happens
Trigger: Event dict whose markets list is empty or non-dict entries only (has_active False, include_closed True, still nothing parses); event fully resolved whose child markets fail the closed-market parsing; event with active=True markets that are all closed=True so they are excluded when has_active is False.
Common situations: Re-verifying odds on a market that resolved between original fetch and refresh; Gamma returning events with markets stripped out; schema drift in Gamma market fields breaking the parser.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Polymarket event was not found
- Polymarket datum {datum_key!r} was not found
- StockTwits symbol stream was not returned
- {status}: {message}
- Polymarket item carries no event id; slug equality alone can
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/4bebc466d667d49a.
Report an issue: GitHub.