mvanhorn/last30days-skill · warning · KeyError

StockTwits stream has no tagged sentiment

Error message

StockTwits stream has no tagged sentiment

What it means

KeyError raised at the end of StockTwits refetch_datum when aggregation over the (date-filtered) message stream yields no pct_bullish - meaning zero messages carry a Bullish/Bearish sentiment tag. The fetch itself succeeded; the population just has no tagged sentiment to compute a percentage from.

Source

Thrown at skills/last30days/scripts/lib/stocktwits.py:340

        if not isinstance(data, dict) or not isinstance(data.get("messages"), list):
            raise KeyError("StockTwits symbol stream was not returned")
        batch = data["messages"]
        if not batch:
            break
        messages.extend(batch)
        cursor = data.get("cursor") or {}
        if not cursor.get("more") or not cursor.get("max"):
            break
        cursor_max = cursor["max"]
    messages = _filter_by_date(
        messages,
        window.get("from_date"),
        window.get("to_date"),
    )
    aggregate = aggregate_sentiment(messages)
    value = aggregate.get("pct_bullish")
    if value is None:
        raise KeyError("StockTwits stream has no tagged sentiment")
    newest = max(
        (str(message.get("created_at") or "") for message in messages),
        default="",
    )
    return {
        "value": value,
        "values": {"pct_bullish": value},
        "url": item.url,
        "timestamp": newest or None,
    }


# --------------------------------------------------------------------------- #
# Standalone CLI (ad-hoc use today, before any engine wiring)                  #
#   python3 stocktwits.py "ServiceNow stock"                                   #
# --------------------------------------------------------------------------- #
if __name__ == "__main__":
    topic = " ".join(sys.argv[1:]) or "$NOW"

View on GitHub (pinned to c7460f6114)

Solutions

  1. Catch KeyError and report 'no tagged sentiment in window' rather than an error
  2. Widen the freshness window (from_date) or increase depth so more tagged messages are included
  3. Pre-check the cached sample: if aggregate sample was near zero originally, skip re-verification

Example fix

# before
val = refetch_datum(item, "pct_bullish")  # KeyError on untagged stream

# after
try:
    val = refetch_datum(item, "pct_bullish")
except KeyError:
    val = {"value": None, "note": "no tagged sentiment in freshness window"}
Defensive patterns

Strategy: fallback

Validate before calling

window = item.metadata.get("freshness_window") or {}
if window.get("from_date") and days_between(window["from_date"], today()) > 30:
    skip_refetch(item)  # window too narrow to expect tagged messages

Try / catch

try:
    datum = refetch_datum(item, "pct_bullish")
except KeyError as e:
    if "no tagged sentiment" in str(e):
        datum = {"value": None, "note": "no tagged sentiment in window"}

Prevention

When it happens

Trigger: refetch_datum paginates fine but every message in the window has entity sentiment or is untagged; or _filter_by_date removes all messages because the freshness window (from_date/to_date) excludes them, leaving an empty list where the bully-share is undefined.

Common situations: Low-volume tickers whose recent messages are mostly untagged; date windows narrowed after the original fetch so nothing remains; symbols whose traders don't use StockTwits sentiment buttons; weekends with no tagged activity.

Related errors


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