Skip to content

WS: _OrderbookIterator yields silently-empty Orderbook when manager has no book #257

Closed

Description

@TexasCoding

Summary

After a gap-triggered remove_by_sid + resubscribe (or in the stale-sid race in a sibling issue), get(ticker) can return None between snapshot teardown and the new snapshot landing in the manager. The iterator hides this as a fully-empty book — a strategy reading bid/ask sees 0-depth, indistinguishable from a real market with no liquidity, and may place orders against an empty book.

Location

  • kalshi/ws/client.py:850-856 — _OrderbookIterator.__anext__

Evidence

async def __anext__(self) -> Orderbook:
    await self._stream.__anext__()
    book = self._mgr.get(self._ticker)
    if book is None:
        # This shouldn't happen after snapshot, but handle gracefully
        return Orderbook(ticker=self._ticker)
    return book

Recommended fix

Raise a KalshiSequenceGapError (or a dedicated KalshiOrderbookUnavailable) instead of returning an empty book; or skip the yield (continue) and wait for the next delta which is necessarily preceded by the resync snapshot. The inline comment already admits this "shouldn't happen" — the recovery path makes it possible.

Severity & category

medium / correctness, ws

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingwsWebSocket-related

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions