Installation Issues
npm install fails (TypeScript)
npm install fails (TypeScript)
npm install kaleido-sdk fails with errorsSolutions:- Ensure Node.js 18+ is installed:
node --version - Clear npm cache:
npm cache clean --force - Delete
node_modulesandpackage-lock.json, then reinstall - Try with a different package manager:
pnpm add kaleido-sdk
pip install fails (Python)
pip install fails (Python)
pip install kaleido-sdk failsSolutions:- Ensure Python 3.10+ is installed:
python --version - Use a virtual environment:
python -m venv .venv && source .venv/bin/activate - Upgrade pip:
pip install --upgrade pip - Try:
pip install kaleido-sdk --no-cache-dir
Module not found, or ERR_REQUIRE_ESM
Module not found, or ERR_REQUIRE_ESM
Cannot find module 'kaleido-sdk', ERR_REQUIRE_ESM, import syntax errors, or ModuleNotFoundErrorCause (TypeScript): The SDK is ESM-only, and the legacy "moduleResolution": "node" setting ignores the package’s exports field.Solutions:- TypeScript: set
"moduleResolution"to"bundler","node16", or"nodenext"intsconfig.json, and make the consuming project ESM —"type": "module"inpackage.json, or the.mtsfile extension. If you must stay on CommonJS, use a dynamic import:const sdk = await import('kaleido-sdk') - Python: Verify you are in the correct virtual environment
- Verify the package is installed:
npm list kaleido-sdkorpip show kaleido-sdk
Runtime Errors
NetworkError: Connection refused
NetworkError: Connection refused
NetworkError when making API callsCauses:- API server unreachable
- Incorrect
baseUrl - Firewall blocking requests
- Verify the
baseUrlis correct and accessible - Check internet connectivity
- Try accessing the API URL in a browser:
https://api.signet.kaleidoswap.com/api/v1/market/assets - If behind a firewall, ensure outbound HTTPS is allowed
Node not configured
Node not configured
ConfigError (“Node API not configured…”) in TypeScript, or NodeNotConfiguredError in Python, when calling client.rln.* methodsCause: No nodeUrl / node_url was provided when creating the client.Solution:client.hasNode() / client.has_node() before calling RLN methods.QuoteExpiredError
QuoteExpiredError
QuoteExpiredError when calling initSwap / init_swap with an rfq_idCause: The quote’s expires_at time has passed.Solutions:- Get a fresh quote immediately before calling
initSwap— do not reuse anrfq_idacross user think-time - Use WebSocket streaming for always-current quotes
- Whitelist and execute promptly; the whole init → whitelist → execute sequence runs against one quote
ValidationError: Invalid amount
ValidationError: Invalid amount
ValidationError with amount-related messageCauses:- Amount below minimum or above maximum
- Wrong precision (sending display units instead of raw)
- Negative or zero amount
- Check min/max limits from the
listPairsresponse - Ensure you are sending raw amounts, not display amounts — convert with
parseRawAmount/parse_raw_amountfrom Utilities - Validate amounts before sending
TimeoutError
TimeoutError
TimeoutError on API callsCauses:- Slow network connection
- Server under heavy load
- Timeout too short
- Increase the timeout:
timeout: 60(seconds) - Check network connectivity
- Implement retry logic using
error.isRetryable()— see Retry Patterns
RateLimitError: 429 Too Many Requests
RateLimitError: 429 Too Many Requests
RateLimitError on repeated calls, typically while polling quotesCause: Too many requests in the rate-limit window.Solutions:- Back off and retry, honouring any
retry_afterthe response carries (in Python,is_retryable()returnsFalsefor rate limits, so back off manually) - Stream quotes over WebSocket instead of polling
getQuotein a loop - Cache
listAssets/listPairsrather than refetching them per operation
Swap Issues
SwapError on execute: swapstring not whitelisted
SwapError on execute: swapstring not whitelisted
initSwap succeeds, but executeSwap / execute_swap fails with SwapErrorCause: The swapstring returned by initSwap was never whitelisted on your own node, so the taker side cannot honour the HTLC.Solution: The three steps must run in order, and the whitelist step is on client.rln, not client.maker:client.maker.initSwap(...)→ returnsswapstringclient.rln.whitelistSwap(swapstring)→ your node accepts the swapclient.maker.executeSwap(...)→ the maker settles it
InsufficientBalanceError
InsufficientBalanceError
InsufficientBalanceError on init or executeCauses:- Not enough outbound capacity on the channel for the leg you are sending
- The dust reserve is not available on top of the swap amount
- Balance is on-chain rather than in a channel
- Check
client.rln.listChannels()for outbound capacity on the right asset, not just total balance - Confirm the amount is within the pair’s min/max from
listPairs - If capacity is short, order more inbound or outbound liquidity via LSPS1
Swap stuck in a pending state
Swap stuck in a pending state
executeSwap returned, but the assets have not arrivedSolutions:- Poll
client.maker.getAtomicSwapStatus(...)/get_atomic_swap_status(...)rather than assuming execute is terminal - Call
client.rln.refreshTransfers()/refresh_transfers()to advance pending RGB transfers - Check
client.rln.listSwaps()for the node’s own view of the swap
Version mismatch: unexpected response shape
Version mismatch: unexpected response shape
ValidationError, or a TypeScript field that is unexpectedly undefined) rather than returning a clean SDK errorCause: The SDK and the API it is talking to were generated against different spec versions. This is most common on the node side, where the RLN version is yours to control.Solutions:- Compare your node’s version against the one your SDK release targets — see RLN API Compatibility
- Upgrade the SDK:
npm install kaleido-sdk@latestorpip install --upgrade kaleido-sdk - Check the Changelog for breaking changes between your version and the current one — several releases added now-required request fields
WebSocket Issues
WebSocket not connecting
WebSocket not connecting
connected event never fires, or WebSocketErrorSolutions:- Verify the WebSocket URL is correct (should start with
wss://) - Ensure
enableWebSocket/enable_websocketwas called before streaming - Check that WebSocket connections are not blocked by firewall or proxy
- Try with a different client ID in the URL
No quotes received
No quotes received
quoteResponse / quote_response event never firesSolutions:- Verify the asset pair is valid and has available routes
- Check that the amount is within min/max limits
- Listen for
errorevents on the WSClient - Verify the connection is established (check
connectedevent)
Frequent disconnections
Frequent disconnections
- Check internet stability
- The WSClient auto-reconnects with exponential backoff
- Monitor
reconnectingevents to track attempts - If
maxReconnectExceededfires, manually reconnect:
Language-Specific Issues
Type errors with OpenAPI types (TypeScript)
Type errors with OpenAPI types (TypeScript)
- Ensure you are importing types from
kaleido-sdk: - Check your TypeScript version is 5.0+
- If using strict mode, you may need to handle
undefinedexplicitly
Pydantic validation errors (Python)
Pydantic validation errors (Python)
ValidationError from Pydantic when parsing API responsesSolutions:- Ensure
pydantic>=2.0is installed - Check that you are using the correct request format
- The API may have been updated — try updating the SDK:
pip install --upgrade kaleido-sdk
httpx connection errors (Python)
httpx connection errors (Python)
httpx.ConnectError or similarSolutions:- Check that the API URL is reachable
- If using a proxy, configure it via environment variables:
HTTP_PROXY,HTTPS_PROXY - Increase timeout if the connection is slow
Error Reference
Both SDKs share a nearly identical error class hierarchy. All errors extend fromKaleidoError, so a single catch on it never lets an SDK failure escape unhandled:
RateLimitErrorextendsAPIErrorin TypeScript butKaleidoErrordirectly in Python — a Pythonexcept APIErrorhandler will not catch rate-limit errors.- A missing node URL raises
NodeNotConfiguredErrorin Python, butConfigError(“Node API not configured. Provide “nodeUrl” when creating the client.”) in TypeScript.
KaleidoError Properties
Every error carries these, whichever class it is:Error Classes
HTTP Error Mapping
The SDK automatically maps HTTP errors to typed exceptions usingmapHttpError / map_http_error:
isRetryable() / is_retryable() — it encodes exactly these rules and stays correct as the mapping evolves.
Comprehensive Error Handling
Branch from the most specific class to the most general, and end onKaleidoError so nothing escapes. Subclasses must be tested before their parents — in TypeScript RateLimitError is an APIError, so an APIError branch placed first would swallow it.
InsufficientBalanceError to show the shortfall, ValidationError to point at the offending field. Everything else is already covered by the isRetryable() check and the base case.
Retry Patterns
UseisRetryable() to implement automatic retries:
Debugging
Enable Verbose Logging
Python exposes the underlyinghttpx and websockets loggers:
logLevel when creating the client for the SDK’s own output — see Configuration — and inspect the wire with NODE_DEBUG=http, or the network panel in your browser’s DevTools.
Validate Configuration
When calls fail before you can pin down a specific error, check these four things in order:The API URL resolves
<baseUrl>/api/v1/market/assets in a browser. The SDK appends /api/v1 itself, so the config value must not already include it.The client sees a node
client.hasNode() / client.has_node() returns false whenever nodeUrl / node_url was omitted, and every client.rln.* call will fail on that alone.The node answers
client.rln.getNodeInfo() / get_node_info() returning a pubkey proves the node is both reachable and unlocked.Both point at the same network
baseUrl paired with a mainnet node yields confusing empty results rather than a clean error.Get Help
Check the FAQ for questions rather than errors, and Additional Resources for upstream documentation and links. For anything else, report a problem through your preferred channel from the options below, including:- SDK version (
getVersion()/get_version()) - Language and runtime version (Node.js / Python)
- Error message and stack trace
- Minimal code to reproduce
- Environment (Signet / Mainnet)