Every error raised by the SDK extends a common base. Faucet-specific codes are surfaced on the error instance (Documentation Index
Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
Use this file to discover all available pages before exploring further.
error.code) so callers can branch without string matching.
Class hierarchy
- JavaScript
- Python
PeaqosError directly. catch (err instanceof PeaqosError) covers every SDK error; catching RuntimeError alone will miss ValueCapExceeded and RateLimitExceeded.Faucet error codes
All 20 codes the Gas Station can return fromPOST /faucet/fund, POST /2fa/setup, and POST /2fa/confirm. Each endpoint returns a subset. For example, INVALID_OWNER_ADDRESS and QR_GENERATION_FAILED only come from /2fa/setup. Codes surface as RuntimeError.code (JS) or ApiError.code (Python).
2FA errors
2FA errors
| Code | Description | Retry |
|---|---|---|
INVALID_2FA | OTP rejected by the faucet | Yes: submit a fresh 6-digit code |
2FA_NOT_CONFIGURED | Owner has not completed setup_faucet_2fa | No: re-run setup |
2FA_NOT_ACTIVE | 2FA enrolled but not confirmed | No: call confirm_faucet_2fa with a valid OTP |
2FA_LOCKED | Too many invalid attempts; owner temporarily blocked | After lockout window |
Idempotency errors
Idempotency errors
| Code | Description | Retry |
|---|---|---|
DUPLICATE_REQUEST | Same request_id already in flight | No: use a different request_id or wait for prior result |
REQUEST_ALREADY_PROCESSED | Same request_id already resolved | No: read the prior result |
Rate limit & cap errors
Rate limit & cap errors
| Code | Description | Retry |
|---|---|---|
RATE_LIMITED | Per-IP or per-wallet throttle hit | After cooldown |
CAP_EXCEEDED_OWNER | Daily per-owner funding cap reached | Next day |
CAP_EXCEEDED_WALLET | Daily per-target-wallet cap reached | Next day, or target a different wallet |
Validation errors
Validation errors
| Code | Description | Retry |
|---|---|---|
INVALID_PAYLOAD | Request body malformed | No: fix the payload |
INVALID_OWNER_ADDRESS | owner_address not a recognized format | No |
INVALID_TARGET_ADDRESS | target_wallet_address not recognized | No |
INVALID_CHAIN_ID | chain_id not configured on the faucet | No |
INVALID_REQUEST_ID | request_id not a UUID | No |
Chain & server errors
Chain & server errors
| Code | Description | Retry |
|---|---|---|
TRANSFER_FAILED | On-chain transfer reverted or stalled | Yes |
CHAIN_RPC_ERROR | Faucet’s RPC call failed | Yes |
INTERNAL_ERROR | Faucet internal failure | Yes |
QR errors
QR errors
| Code | Description | Retry |
|---|---|---|
QR_NOT_FOUND | QR image expired or never created | No: re-run setup |
QR_EXPIRED | QR retrieval attempted after ~2 min TTL | No: re-run setup |
QR_GENERATION_FAILED | Faucet could not generate the image | Yes |
On-chain revert names
Revert names the SDK translates to a friendly message and surfaces asRuntimeError.code (JS) or RpcError.code (Python). The contracts define more custom errors than this table; anything not listed surfaces as code: "TX_REVERTED" (Python) or code: "<RawErrorName>" with a generic Transaction reverted: … message (JS, when viem decodes the selector).
| Revert | Raised by | Cause |
|---|---|---|
AlreadyRegistered | registerMachine / registerFor / register_machine | Address already has a machine ID |
InvalidMachineAddress | registerFor | machineAddress is the zero address |
InvalidAddress | Staking / NFT flows | Caller passed the zero address where a real address is required |
AmountZero | Staking / bond flow | Bond amount is zero |
AlreadyStaked | Staking flow | Machine is already bonded/staked |
MachineNotBonded | mintNft / mint_nft | Caller’s machine is not bonded on the IdentityRegistry |
AlreadyMinted | mintNft / mint_nft | An NFT is already minted for the machine |
NotMachineOwner | mintNft / mint_nft | Caller is not the owner of the machine |
RecipientMustBeMachineOwner | mintNft / mint_nft | Operator-mint guard: recipient must be the registered machine owner |
MachineNotFound | submitEvent / tokenIdOf | machineId has no Identity record on the IdentityRegistry |
MachineDeactivated | submitEvent | The machine has been deactivated by the IdentityRegistry |
NotAuthorizedSubmitter | submitEvent | Caller is not authorized to submit events for this machine |
InvalidEventType | submitEvent | eventType is not 0 (revenue) or 1 (activity) |
InvalidTrustLevel | submitEvent | trustLevel is not 0, 1, or 2 |
MCR API error codes
Returned byqueryMcr / query_mcr, queryMachine / query_machine, and queryOperatorMachines / query_operator_machines. Surfaced as RuntimeError.code (JS) or ApiError.code (Python).
| Code | Cause | Retry |
|---|---|---|
NOT_FOUND | The DID, machine, or token ID was not found by the MCR API (HTTP 404) | No: check the input |
BAD_RESPONSE | The MCR returned an unexpected payload shape | No: file an issue if it persists |
HTTP_ERROR | The MCR returned an unhandled non-2xx status | Maybe: surface the status code and decide |
SERVER_ERROR | The MCR returned 5xx | Yes, with backoff |
SERVICE_UNAVAILABLE | The MCR returned 503 (Service not initialised / Chain unavailable) | Yes, with backoff |
TIMEOUT | The HTTP request exceeded timeoutMs | Yes |
NETWORK_ERROR | Transport-level failure (DNS, TCP, TLS) | Yes |
ABORTED | The caller aborted the request via AbortSignal (JS only) | Caller’s choice |
OWS signing error codes
Raised when transaction signing routes through an OWS vault wallet (PeaqosClient.fromWallet / from_wallet with owsSigning=true). The SDK normalises the upstream OWS error code into a typed SDK exception — only INVALID_INPUT becomes ValidationError; the other four become PeaqosError (or RuntimeError in JS) with the original OWS error preserved as .cause.
| Code | Cause | Surfaces as |
|---|---|---|
WALLET_NOT_FOUND | Vault wallet name / UUID does not exist | PeaqosError (Py) / RuntimeError (JS) |
INVALID_PASSPHRASE | Wrong vault passphrase | PeaqosError (Py) / RuntimeError (JS) |
INVALID_INPUT | Malformed transaction or sign-hash payload | ValidationError(field="transaction") |
POLICY_DENIED | Signing blocked by an OWS policy rule | PeaqosError (Py) / RuntimeError (JS) |
CHAIN_NOT_SUPPORTED | Transaction chainId is not configured in OWS | PeaqosError (Py) / RuntimeError (JS) |
OWS_ERROR_WALLET_NOT_FOUND, OWS_ERROR_INVALID_PASSPHRASE, OWS_ERROR_INVALID_INPUT, OWS_ERROR_POLICY_DENIED, OWS_ERROR_CHAIN_NOT_SUPPORTED. JS additionally exports the OwsSigningErrorCode union type.
SDK transaction sentinels
Raised by the SDK’s transaction helper around any contract call. Surfaced asRuntimeError.code (JS) or RpcError.code (Python).
| Code | Cause |
|---|---|
WALLET_NOT_CONFIGURED | Method requires a signer but none was configured. (JS only; the Python PeaqosClient constructor requires a private_key and surfaces this as ValidationError.) |
TX_REVERTED | The transaction reverted on-chain. The revert reason is in the message; revert names from the table above are decoded into code when the SDK recognizes them. |
RECEIPT_AWAIT_FAILED | Transaction was submitted but the SDK could not retrieve a receipt. The tx may still have landed; re-query by hash before retrying. |
REGISTERED_EVENT_MISSING | Receipt has no Registered event log. Indicates a contract/SDK ABI mismatch. |
REGISTERED_EVENT_MALFORMED | Registered event log was decoded but had unexpected fields. Same root cause as above. |
INVALID_FEE_RESULT | quoteSend on the LayerZero ONFT adapter returned a malformed MessagingFee. Raised inside bridge_nft (Python) before submission. |
Faucet / HTTP envelope sentinels
Raised by the SDK when a faucet or MCR response is reachable but unparseable. Surfaced asApiError.code (Python). The JS SDK collapses these into the generic RuntimeError envelope path.
| Code | Cause |
|---|---|
INVALID_RESPONSE | Faucet returned a non-JSON body. |
UNEXPECTED_RESPONSE | Faucet returned JSON but the status / code / data envelope did not match the expected shape for the endpoint. |
NETWORK_ERROR | Transport-level failure during a faucet call (DNS, connection refused, TLS, timeout via requests.RequestException). Same sentinel as the MCR API table above. |
Client-side error codes
Raised by the SDK itself (not by a chain revert). Surfaced asRuntimeError.code (JS) or ValidationError/RpcError attributes (Python).
| Code | Raised by | Cause |
|---|---|---|
MIN_BOND_INVALID_RESULT | registerMachine / registerFor (JS only) | IdentityRegistry.minBond() returned a non-bigint value before submitting the bond. |
Error handling patterns
- JavaScript
- Python

