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

  1. Re-derive datum keys from the refreshed outcome_prices list rather than reusing keys from the original parse
  2. Catch KeyError and fall back to listing available outcome names so the caller can re-select
  3. 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

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


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/af3f45c6aeeed50d. Report an issue: GitHub.