> For the complete documentation index, see [llms.txt](https://docs.opinion.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opinion.trade/developer-guide/opinion-clob-typescript-sdk/support/troubleshooting.md).

# Troubleshooting

Common issues and solutions for the TypeScript SDK (`@opinion-labs/opinion-clob-sdk` v0.5.2).

***

## Installation Issues

### Cannot find module '@opinion-labs/opinion-clob-sdk'

**Problem:** TypeScript or Node.js cannot locate the SDK package.

**Solution:**

{% stepper %}
{% step %}

### Verify installation

Run:

```bash
npm list @opinion-labs/opinion-clob-sdk
```

{% endstep %}

{% step %}

### Install the package

If not installed, run:

```bash
npm install @opinion-labs/opinion-clob-sdk
```

{% endstep %}

{% step %}

### Monorepo/workspace check

If using a monorepo or workspace, ensure the dependency is in the correct `package.json`.
{% endstep %}
{% endstepper %}

***

### ERR\_REQUIRE\_ESM or "require() of ES Module not supported"

**Problem:** The SDK is an ESM (ECMAScript Module) package, but your project uses CommonJS `require()`.

**Solution:**

Option A - Switch your project to ESM:

Add `"type": "module"` to your `package.json`:

```json
{
  "type": "module"
}
```

Option B - Use dynamic import in CommonJS:

```javascript
async function main() {
  const { Client } = await import('@opinion-labs/opinion-clob-sdk');
  // Use Client normally
}
main();
```

***

### TypeScript compiler errors with viem types

**Problem:** Type errors related to `Address`, `Hex`, or other viem types.

**Solution:**

Ensure your `tsconfig.json` has the following settings:

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "node16",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true
  }
}
```

Key requirements:

* `target` must be `ES2020` or later (for BigInt support).
* `moduleResolution` should be `node16` or `bundler`.
* `skipLibCheck: true` helps avoid transitive type conflicts.

***

### Node.js version compatibility

**Problem:** Runtime errors or unexpected behavior.

**Solution:** The SDK requires Node.js 18 or later. Check your version:

```bash
node --version
```

If below v18, upgrade Node.js. The SDK uses features like native `fetch`, BigInt, and ES modules.

***

## Configuration Errors

### "chainId must be one of 56" (Unsupported Chain ID)

**Problem:** `InvalidParamError` thrown during `Client` initialization.

**Cause:** Only BNB Chain mainnet (chain ID 56) is currently supported.

**Solution:**

```typescript
import { Client, CHAIN_ID_BNB_MAINNET } from '@opinion-labs/opinion-clob-sdk';

const client = new Client({
  // ...
  chainId: CHAIN_ID_BNB_MAINNET,  // Always use 56
});
```

***

### Missing Environment Variables

**Problem:** Client initialization fails due to missing credentials.

**Solution:**

{% stepper %}
{% step %}

### Provide required fields to Client

```typescript
const client = new Client({
  host: process.env.API_HOST || 'https://openapi.opinion.trade/openapi',
  apiKey: process.env.API_KEY!,           // Required
  chainId: 56,
  rpcUrl: process.env.RPC_URL!,           // Required
  privateKey: process.env.PRIVATE_KEY!,   // Required (0x-prefixed)
  multiSigAddress: process.env.MULTI_SIG_ADDRESS!,  // Required
});
```

{% endstep %}

{% step %}

### Create a .env file

```
API_KEY=your_api_key
RPC_URL=https://bsc-dataseed.binance.org
PRIVATE_KEY=0xYOUR_PRIVATE_KEY
MULTI_SIG_ADDRESS=0xYOUR_MULTI_SIG_ADDRESS
```

{% endstep %}

{% step %}

### Load environment variables

Use a library like `dotenv` to load it:

```typescript
import 'dotenv/config';
```

{% endstep %}
{% endstepper %}

***

## API and Trading Errors

### Common errno Values

| errno | Meaning                  | How to Fix                                           |
| ----- | ------------------------ | ---------------------------------------------------- |
| 0     | Success                  | No action needed                                     |
| 100   | Invalid API key          | Verify API key, check for extra whitespace           |
| 200   | Market not found         | Verify market ID exists and is correct               |
| 201   | Market not active        | Market is not in ACTIVATED status                    |
| 300   | Order not found          | Verify order ID (trans\_no)                          |
| 301   | Order cannot be canceled | Order is already filled, canceled, or expired        |
| 303   | Insufficient balance     | Deposit more funds or cancel other open orders       |
| 304   | Price out of range       | Price must be between 0 and 1 for prediction markets |
| 305   | Amount too small         | Increase order amount (minimum 1 unit)               |
| 429   | Rate limit exceeded      | Reduce request frequency, implement backoff          |
| 500   | Internal server error    | Retry after a short delay                            |

***

### InvalidParamError: "makerAmountInBaseToken is not allowed for market buy"

**Problem:** Attempting a market buy order with `makerAmountInBaseToken`.

**Solution:** Market buy orders must use `makerAmountInQuoteToken`:

```typescript
// Correct - Market buy with quote token amount
const orderData: PlaceOrderDataInput = {
  marketId: 57,
  tokenId: 'TOKEN_ID',
  makerAmountInQuoteToken: '100',  // Use quote token for market buys
  orderType: OrderType.MARKET_ORDER,
  side: OrderSide.BUY,
  price: '0',
};
```

***

### InvalidParamError: "makerAmountInQuoteToken is not allowed for market sell"

**Problem:** Attempting a market sell order with `makerAmountInQuoteToken`.

**Solution:** Market sell orders must use `makerAmountInBaseToken`:

```typescript
// Correct - Market sell with base token (shares) amount
const orderData: PlaceOrderDataInput = {
  marketId: 57,
  tokenId: 'TOKEN_ID',
  makerAmountInBaseToken: '10',  // Use base token for market sells
  orderType: OrderType.MARKET_ORDER,
  side: OrderSide.SELL,
  price: '0',
};
```

***

### OpenApiError: "Quote token not found for this market"

**Problem:** The market's quote token is not in the list of supported quote tokens.

**Solution:**

1. Ensure you are using the correct chain ID (56).
2. Call `getQuoteTokens()` to see supported tokens.
3. Verify the market's quote token matches one of the supported tokens.

***

### OpenApiError: "Cannot place order on different chain"

**Problem:** The market belongs to a different chain than the client is configured for.

**Solution:** Ensure your `chainId` matches the market's chain. Currently only chain ID 56 (BNB Chain) is supported.

***

### Rate Limiting (errno: 429)

**Problem:** Too many requests in a short period.

**Solution:** Implement exponential backoff:

```typescript
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof OpenApiError && error.message.includes('rate limit')) {
        const waitTime = Math.pow(2, attempt) * 1000;
        console.log(`Rate limited, waiting ${waitTime}ms...`);
        await new Promise((resolve) => setTimeout(resolve, waitTime));
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}
```

***

## Blockchain Issues

### InsufficientGasBalance

**Problem:** The signer wallet does not have enough BNB for gas fees.

**Solution:**

{% stepper %}
{% step %}

### Check signer wallet balance

Check the BNB balance of your **signer wallet** (the wallet corresponding to `privateKey`).
{% endstep %}

{% step %}

### Deposit BNB

Deposit BNB to the signer wallet address.
{% endstep %}

{% step %}

### Know which ops require gas

Gas is required for `enableTrading()`, `split()`, `merge()`, and `redeem()`.
{% endstep %}

{% step %}

### Note about orders

Placing and canceling orders does NOT require gas (they are off-chain signed operations).
{% endstep %}
{% endstepper %}

***

### Transaction Reverted

**Problem:** An on-chain transaction reverts.

**Common causes and solutions:**

* split fails: Check that you have enough collateral (USDC) in your asset wallet. The market must be in ACTIVATED, RESOLVING, or RESOLVED status.
* merge fails: You need equal amounts of Yes and No tokens. Check your position balances.
* redeem fails: Market must be in RESOLVED status. You must hold winning outcome tokens.
* enableTrading fails: Check that the signer wallet has enough BNB for gas.

***

### Wrong Contract Addresses

**Problem:** Transactions fail because of incorrect contract addresses.

**Solution:** The SDK uses default contract addresses for BNB Chain. If you need to override them:

```typescript
const client = new Client({
  // ... other options
  conditionalTokensAddress: '0x...',
  multiSendAddress: '0x...',
  feeManagerAddress: '0x...',
  ctfExchangeAddress: '0x...',
});
```

Only override these if instructed by the Opinion Labs team.

***

## WebSocket Issues

### "WebSocket is not connected. Call connect() first."

**Problem:** Attempting to subscribe or send messages before the WebSocket connection is established.

**Solution:** Always `await` the `connect()` call before subscribing:

```typescript
const wsClient = client.createWebSocketClient({
  onOpen: () => console.log('Connected'),
});

await wsClient.connect();  // Wait for connection

// Now safe to subscribe
wsClient.subscribeMarketDepthDiff(1274, (msg) => {
  console.log(msg);
});
```

***

### WebSocket connection drops

**Problem:** WebSocket disconnects unexpectedly.

**Solution:**

{% stepper %}
{% step %}

### Heartbeat

The SDK sends automatic heartbeat messages (default every 30 seconds).
{% endstep %}

{% step %}

### Reconnect on close

Use the `onClose` callback to detect disconnections and implement reconnection logic:

```typescript
const wsClient = client.createWebSocketClient({
  onClose: async () => {
    console.log('Disconnected, reconnecting...');
    await wsClient.connect();
    // Re-subscribe to channels
  },
});
```

{% endstep %}
{% endstepper %}

***

## Performance Tips

### Use Caching

The SDK caches quote tokens (1 hour) and market data (5 minutes) by default. Avoid setting TTLs to 0 unless you need real-time data:

```typescript
const client = new Client({
  // ...
  quoteTokensCacheTtl: 3600,   // 1 hour (default)
  marketCacheTtl: 300,          // 5 minutes (default)
});
```

### Batch Operations

Use batch methods for multiple orders:

```typescript
// Instead of multiple placeOrder calls:
const results = await client.placeOrdersBatch(orders);

// Instead of multiple cancelOrder calls:
const results = await client.cancelOrdersBatch(orderIds);

// Cancel all at once:
const result = await client.cancelAllOrders({ marketId: 57 });
```

### Pre-enable Trading

Call `enableTrading()` once at startup rather than passing `checkApproval: true` on every order:

```typescript
// Do this once at startup
await client.enableTrading();

// Then place orders without approval check
await client.placeOrder(orderData, false);  // checkApproval = false
```

### Use Proxy for Network Restrictions

If you are behind a firewall or in a region with network restrictions, configure a proxy:

```typescript
const client = new Client({
  // ...
  proxyUrl: 'http://127.0.0.1:7890',
});
```

This applies to both HTTP API calls and WebSocket connections.

***

## Support

If you are unable to resolve your issue with the information above:

* Documentation: <https://docs.opinion.trade>
* Email: <support@opinion.trade>
* GitHub Issues: Report bugs on the SDK repository


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opinion.trade/developer-guide/opinion-clob-typescript-sdk/support/troubleshooting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
