hpyhacking/peatio · warning · Grape::Exceptions::Validation
1001
1001
Error message
must be in range: #{@range} What it means
Peatio APIv2 error code 1001 (HTTP 400). APIv2::Validations::Range is a custom Grape validator bound to the `range:` option; validate_param! raises Grape::Exceptions::Validation unless @range.cover?(value). It guards the `limit` parameter on GET /api/v2/orders and the shared trade_filters (both `range: 1..1000`), and the rescue_from handler renders {error: {code: 1001, message: "limit must be in range: 1..1000"}}. The guard `(params[attr_name] || @required)` means an absent optional parameter skips the check — only a supplied out-of-range value fails.
Source
Thrown at app/api/api_v2/validations.rb:13
module APIv2
module Validations
class Range < ::Grape::Validations::Validator
def initialize(attrs, options, required, scope)
@range = options
@required = required
super
end
def validate_param!(attr_name, params)
if (params[attr_name] || @required) && !@range.cover?(params[attr_name])
raise Grape::Exceptions::Validation, param: @scope.full_name(attr_name), message: "must be in range: #{@range}"
end
end
end
end
end
View on GitHub (pinned to dab8641137)
Solutions
- Clamp limit into 1..1000 before the call, or omit it entirely — server defaults are 100 for /orders and 50 for /trades.
- Paginate with page + limit instead of raising limit.
- Validate the parameter client-side (integer, 1..1000) before building the signed payload.
Example fix
# before get '/orders', market: 'btcusd', limit: 5000 # 1001: limit must be in range: 1..1000 # after limit = [[limit.to_i, 1].max, 1000].min get '/orders', market: 'btcusd', limit: limit, page: page
Defensive patterns
Strategy: validation
Validate before calling
# Ruby: clamp before building the signed request limit = [[params[:limit].to_i, 1].max, 1000].min client.get '/api/v2/orders', market: 'btcusd', limit: limit, page: page
Type guard
// TypeScript: narrow a limit before it reaches the request builder const isValidLimit = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 1000;
Try / catch
If a 1001 'must be in range' response still arrives, re-issue the identical request once with limit clamped to the range stated in the message; do not retry unchanged.
Prevention
- Centralize a clampPeatioLimit() helper in one request builder so every paginated call is covered.
- Omit optional limit to accept server defaults (100 for /orders, 50 for /trades) in configs that never need bigger pages.
- Add an integration test that paginates with the boundary values 1 and 1000.
- Never overload limit to mean page size across exchanges — keep per-exchange caps in config.
When it happens
Trigger: GET /api/v2/orders?market=btcusd&limit=0, limit=-1, or limit=1001 and beyond; GET /api/v2/trades (and other endpoints using trade_filters) with limit outside 1..1000; any client that encodes 'unlimited' as a very large or zero limit value.
Common situations: Porting a bot from an exchange whose page-size cap is 5000; passing limit=0 intending 'use default'; page-size values shared across APIs with different caps; non-integer strings that fail Integer coercion before the range check is even reached.
Related errors
AI-assisted analysis of hpyhacking/peatio@dab8641137 (2026-08-23).
Data as JSON: /api/errors/1545997e0c9b7ffb.
Report an issue: GitHub.