mvanhorn/last30days-skill · error · KeyError
Polymarket datum {datum_key!r} was not found
Error message
Polymarket datum {datum_key!r} was not found What it means
KeyError raised when the requested datum key (outcome name, optionally with a \x1f occurrence suffix for duplicate outcome labels) does not match any outcome in the refreshed event's outcome_prices list. Casefolded comparison is used, and occurrence indexing handles repeated labels like multiple 'Yes' markets.
Source
Thrown at skills/last30days/scripts/lib/polymarket.py:1050
if refreshed.get("end_date") is not None:
values["end_date"] = refreshed["end_date"]
if datum_key == "end_date":
value = values.get("end_date")
else:
if "\x1f" in datum_key:
outcome_name, raw_occurrence = datum_key.rsplit("\x1f", 1)
occurrence = int(raw_occurrence)
else:
outcome_name, occurrence = datum_key, 0
matches = [
price
for name, price in refreshed.get("outcome_prices") or []
if str(name).casefold() == outcome_name.casefold()
]
value = matches[occurrence] if occurrence < len(matches) else None
if value is None:
raise KeyError(f"Polymarket datum {datum_key!r} was not found")
return {
"value": value,
"values": values,
"url": str(getattr(item, "url", "")),
"timestamp": event.get("updatedAt"),
}
View on GitHub (pinned to c7460f6114)
Solutions
- Re-derive datum keys from the refreshed outcome_prices list rather than reusing keys from the original parse
- Catch KeyError and fall back to listing available outcome names so the caller can re-select
- For multi-occurrence keys, clamp the occurrence index to len(matches) - 1 when exact occurrence no longer exists
Example fix
# before
value = refetch_datum(item, "Yes\x1f2") # KeyError if only 1 'Yes' left
# after
matches = [n for n, _ in refreshed_outcomes if n.casefold() == "yes"]
key = "Yes" if len(matches) == 1 else f"Yes\x1f{min(2, len(matches)-1)}"
value = refetch_datum(item, key) Defensive patterns
Strategy: try-catch
Validate before calling
def datum_key_exists(refreshed_outcomes, datum_key: str) -> bool:
if "\x1f" in datum_key:
name, occ = datum_key.rsplit("\x1f", 1)
occ = int(occ)
else:
name, occ = datum_key, 0
matches = [n for n, _ in refreshed_outcomes or [] if str(n).casefold() == name.casefold()]
return occ < len(matches) Try / catch
try:
value = refetch_datum(item, datum_key)
except KeyError as e:
if "datum" in str(e):
available = [n for n, _ in refreshed_outcomes]
reselect_outcome(available) Prevention
- Re-derive datum keys from the refreshed outcome list each verification cycle
- Clamp occurrence suffixes to the current number of same-labeled outcomes
- Store the outcome label plus event id, not positional assumptions
When it happens
Trigger: refetch_datum(item, datum_key) where datum_key names an outcome ('Yes', 'No', custom label) absent from refreshed['outcome_prices']; or the occurrence number (after \x1f split) exceeds the count of casefolded matches, so matches[occurrence] would be out of range and value stays None.
Common situations: Event outcome labels renamed between original fetch and refresh (e.g. a candidate dropping out relabels markets); datum keys built against an older parse of the event; multi-market events where the number of same-labeled outcomes shrank.
Related errors
- Polymarket event was not found
- Polymarket event is closed, unavailable, or malformed
- Polymarket item carries no event id; slug equality alone can
- Polymarket item has no event id or slug
- StockTwits symbol stream was not returned
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/af3f45c6aeeed50d.
Report an issue: GitHub.