Skip to content

orders.create() silently defaults count=1 and action="buy" on the kwarg path #242

Closed

Description

@TexasCoding

Summary

Money risk. For a real-money SDK the kwarg-form client.orders.create(ticker=..., side="yes") quietly places a 1-contract BUY when the caller forgot count/action (or typoed the kwarg name). Materializing client-side defaults — instead of omitting and letting the server default apply (or raising) — converts a missing-arg bug into a real fill. The request= overload is unaffected; only the convenience kwargs are.

Location

  • kalshi/resources/orders.py:97-120 — sync create
  • kalshi/resources/orders.py:378-394 — async create
  • kalshi/resources/orders.py:840-856 — _build_create_body helper

Evidence

request = CreateOrderRequest(
    ticker=ticker,
    side=side,
    action=action if action is not None else "buy",
    count=to_decimal(count if count is not None else 1),
    yes_price=to_decimal(yes_price) if yes_price is not None else None,
    ...
)

Recommended fix

Drop the silent defaults: require count and action in the kwarg overload (raise TypeError when None, mirroring the ticker/side guard right above), or omit them from the body so the server applies its own default. Document either way in the docstring. Add a regression test that calls orders.create(ticker="X", side="yes") and asserts the call raises rather than silently placing.

Severity & category

high / api-design, correctness

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions