hpyhacking/peatio · error · APIv2::OrderNotFoundError

2004

2004

Error message

Order##{id} doesn't exist.

What it means

Peatio APIv2 error code 2004 (HTTP 404), raised by GET /api/v2/order. The endpoint runs current_user.orders.where(id: params[:id]).first, so the lookup covers only orders owned by the authenticated member. When no own order carries that id, it raises OrderNotFoundError and returns {error: {code: 2004, message: "Order##{id} doesn't exist."}}. An order that exists under a different member is indistinguishable from one that never existed.

Source

Thrown at app/api/api_v2/orders.rb:32

    end
    get "/orders" do
      orders = current_user.orders
        .order(order_param)
        .with_currency(current_market)
        .with_state(params[:state])
        .page(params[:page])
        .per(params[:limit])

      present orders, with: APIv2::Entities::Order
    end

    desc 'Get information of specified order.', scopes: %w(history trade)
    params do
      use :auth, :order_id
    end
    get "/order" do
      order = current_user.orders.where(id: params[:id]).first
      raise OrderNotFoundError, params[:id] unless order
      present order, with: APIv2::Entities::Order, type: :full
    end

    desc 'Create multiple sell/buy orders.', scopes: %w(trade)
    params do
      use :auth, :market
      requires :orders, type: Array do
        use :order
      end
    end
    post "/orders/multi" do
        orders = create_orders params[:orders]
        present orders, with: APIv2::Entities::Order
    end

    desc 'Create a Sell/Buy order.', scopes: %w(trade)
    params do
      use :auth, :market, :order

View on GitHub (pinned to dab8641137)

Solutions

  1. List your own orders with GET /api/v2/orders (use state and page filters) and confirm the id appears under the same access key that signs the request.
  2. Verify the access_key belongs to the member that created the order; switch to the correct key or re-create the order under the current account.
  3. Keep order ids as strings end to end so they are not float-rounded or truncated before the call.
  4. Treat code 2004 as terminal: do not retry the same request; drop the stale local reference to that order.

Example fix

// before
const order = await peatio.get('/order', { id }); // 2004 => request fails, bot crashes

// after
const res = await peatio.get('/order', { id }).catch(e => e);
if (res?.error?.code === 2004) {
  // not owned by this account or no longer referenceable
  forgetOrder(id);
} else {
  useOrder(res);
}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby client: confirm the id belongs to the signing account before GET /order
mine = client.get '/api/v2/orders', market: 'btcusd', state: 'wait'   # own orders only
own_ids = mine.map { |o| o['id'] }
raise "id #{id} not owned by this account" unless own_ids.include?(id)
order = client.get '/api/v2/order', id: id

Type guard

// TypeScript: order ids are opaque positive integers — narrow before use
const isOrderId = (v: unknown): v is number =>
  typeof v === 'number' && Number.isInteger(v) && v > 0;

Try / catch

Catch the HTTP 404 whose body.error.code === 2004 and treat it as terminal: remove the order from local state and continue; never retry the same id unchanged.

Prevention

When it happens

Trigger: GET /api/v2/order signed with account A's access key while the id was created by account B; a typo'd, truncated, or zero id; an id copied from another environment (staging vs production) or from data predating a database restore. The token must carry the history or trade scope, and the id must be an integer (params :order_id requires type Integer).

Common situations: A bot replays cached order ids from a testnet deployment against production; two API keys for two accounts and the client signs with the wrong one; ids serialized through JavaScript lose precision above 2^53; long-gone orders still referenced by a local cache after a DB purge.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of hpyhacking/peatio@dab8641137 (2026-08-23). Data as JSON: /api/errors/956ddf3f64fdb383. Report an issue: GitHub.