Errors and troubleshooting

What each SDK error means, and fixes for the problems people meet first.

In development. Not released yet; names and formats may change.View as Markdown

Errors and answers

An answer is never an error. ALLOW, CUT, BLOCK and reTrade not answering all come back as a result. Errors are for your code to fix, and every one is a ReTradeError. The names are the same in both SDKs.

The SDK’s errors
ErrorWhenWhat to do
InvalidInputA value the SDK can’t send: a float price, a limit order without a limit price, a stop price of 0, a time without a timezone.Fix the order or the adapter’s data.
ConfigErrorA malformed key id, root key or server address, or an adapter whose settings differ from the account’s at reTrade.Fix the setup.
RequestRefusedreTrade refused a request as malformed or unauthorised: a 4xx other than 429. It has status and detail.Don’t retry: fix the request or the key.
KeyFileErrorThe key file can’t be created or used.See below.
VerificationFailedSomething claiming to be from reTrade failed a check, outside place: the key list, the status or a log record.Check the root key and the address. The SDK never acts on it.
UnreachableNo usable answer in time, from a call other than place, which blocks the order instead.Retry later.
BrokerRejectedRaised by your adapter’s submit when the broker definitely refused the order.Nothing: the SDK reports it as rejected.

Setup problems

KeyFileError: the key is accessible by its group or others

The SDK refuses a key file other users can read. Run chmod 600 executor.pem.

KeyFileError: the key already exists

retrade keygen never overwrites a key. Choose another path, or keep using the key you have.

ConfigError: not an executor key id

A bot key id is exk_, the mode (enforce, shadow or test), _, then 26 characters. Copy it exactly as your admin sent it.

ConfigError: root_key is not a base64url Ed25519 public key

The root key is 43 characters of base64url. Check for a missing character or stray quotes.

VerificationFailed: bad signature on a retrade-keys document

The key list at your server address wasn’t signed by the root key you pinned. Check RETRADE_ROOT_KEY, and that RETRADE_BASE_URL, if it’s set, points at the right server.

ConfigError: plain http is allowed only for a loopback address

Use https, or http only for a server on your own machine (127.0.0.1, localhost or ::1).

ConfigError: the adapter’s settings differ from the account’s

Your adapter’s g_seconds and converts_cash (gSeconds and convertsCash) must equal the account’s settings at reTrade. Ask your admin for them.

ConfigError: the adapter returned no quote

When instrument is given, your adapter’s snapshot function must return a quote for it.

InvalidInput: a price must be a Decimal or a decimal string

Money is exact. In Python use Decimal("187.25"), or Decimal(str(x)) for a float your broker gives you; in TypeScript use "187.25" or String(x), never 187.25.

Node prints an ExperimentalWarning for SQLite

The TypeScript SDK keeps its claim kit with Node’s built-in node:sqlite. On Node 22, Node warns about it; the warning changes nothing.

Problems with answers

Every order comes back unreachable

The SDK couldn’t get an answer within 2.5 seconds. From the machine your bot runs on, check that curl https://api.retrade.app/healthz answers {"ok":true}, that RETRADE_BASE_URL isn’t set to an old address, and that outgoing HTTPS is allowed.

Answers come back unverified

Most often it’s your clock: the SDK refuses an answer made more than 60 seconds from your clock, so turn on time sync (NTP). Otherwise the answer failed a signature or order check, and the SDK’s log says which.

BLOCK with QUOTE-STALE, STATE-STALE or STATE-MISSING

Your adapter sent an old quote or old account data. Read both from the broker each time snapshot is called, and set as_of to when you read them. A price older than 30 seconds is a BLOCK.

BLOCK with STATE-INCOMPLETE on a market buy

For a market buy of a stock the account doesn’t hold, include a position of 0 shares with its current mark.

BLOCK with STATE-JUMP

The account’s value jumped since its last accepted data. Send the deposits, withdrawals, dividends, fees, transfers and splits since adjustments_since as adjustments, or have an admin confirm the data.

BLOCK with ACCOUNT-UNKNOWN

The account ref isn’t in your tenant’s register. Check it with your admin.

A result with reason expired

The approval ran out before the broker call: 30 seconds by default, counted from when the SDK sent the request. Nothing was placed. Ask again.

A placement of unknown

Your adapter’s submit raised something other than BrokerRejected, and find couldn’t see the order. The broker may still have it. Don’t send it again: reconcile from the broker’s own order list. The decision keeps counting at reTrade until the account data shows the order or its absence.

send_snapshot raises RequestRefused (HTTP 404)

Snapshots sent with no order aren’t built on the hosted service yet. keep_fresh (keepFresh) only logs the 404.

Check the service

Terminal
curl -fsS https://api.retrade.app/healthz

It answers {"ok":true} when the hosted service is up.

Still stuck? Your admin can see your tenant’s settings. For a pilot, ask on the home page.