> For the complete documentation index, see [llms.txt](https://help.multisig.ledger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.multisig.ledger.com/guides/api-guides/7.-troubleshooting.md).

# 7. Troubleshooting

Common integration failures and fixes for the Ledger Multisig API tutorials.

<details>

<summary><code>TypeError: SafeApiKit is not a constructor</code></summary>

#### Cause

ESM/CJS interop differences in `@safe-global/api-kit` and `@safe-global/protocol-kit`.

#### Fix

Use interop-safe constructor resolution:

```typescript
import SafeApiKitModule from "@safe-global/api-kit";

const SafeApiKit =
  typeof SafeApiKitModule === "function"
    ? SafeApiKitModule
    : (SafeApiKitModule as unknown as { default: typeof SafeApiKitModule }).default;
```

Apply the same pattern for `SafeModule` from `@safe-global/protocol-kit`.

</details>

<details>

<summary><code>isExecuted</code> is <code>false</code> right after execution</summary>

#### Cause

Transaction Service indexing lag. Execution is on-chain, but API indexing is delayed.

#### Fix

* Wait 10-60 seconds, then query again.
* Verify by `safeTxHash` directly (`getTransaction(safeTxHash)`), not by "latest tx".

</details>

<details>

<summary><code>executeTransaction</code> returns hash but tx failed</summary>

#### Cause

`executeTransaction` can return a submitted hash even when the EVM call reverts.

#### Fix

Always wait for receipt and check status:

```typescript
const receipt = await publicClient.waitForTransactionReceipt({
  hash: executionResult.hash as `0x${string}`,
  timeout: 120_000,
});

if (receipt.status === "reverted") {
  throw new Error("Transaction reverted on-chain");
}
```

</details>

<details>

<summary>Wrong <code>confirmationsRequired</code> after threshold/owner change</summary>

#### Cause

Safe state changed on-chain, but Transaction Service still serves stale indexed state.

#### Fix

Poll `getSafeInfo` until `threshold` matches expected value before proposing the next tx in the flow.

</details>

<details>

<summary><code>getSafeBalances</code> method missing</summary>

#### Cause

`@safe-global/api-kit` v2.5.7 does not wrap balances.

#### Fix

Use direct HTTP request:

```http
GET /v2/safes/{address}/balances/
```

under the configured base URL:

```http
https://app.multisig.ledger.com/api/safe-transaction-service/{chainId}
```

</details>

<details>

<summary>Private key formatting issues (<code>0x0x...</code>)</summary>

#### Cause

Mixing prefixed and non-prefixed private key formats.

#### Fix

Normalize once:

```typescript
function normalizePrivateKey(key: string): `0x${string}` {
  return (key.startsWith("0x") ? key : `0x${key}`) as `0x${string}`;
}
```

</details>

<details>

<summary>RPC instability on Sepolia</summary>

#### Cause

Public Sepolia RPC endpoints can be slow or timeout.

#### Fix

* Retry with backoff.
* Use a dedicated provider (Alchemy/Infura/QuickNode) for stable integration tests.

</details>

<details>

<summary>URL confusion: public Safe service vs Ledger-hosted service</summary>

#### Cause

Using public Safe Transaction Service endpoints by mistake.

#### Fix

Use Ledger-hosted base URL:

```http
https://app.multisig.ledger.com/api/safe-transaction-service/{chainId}
```

Transactions proposed through this backend appear in Ledger Multisig UI.

</details>

## See also

* [Tutorial index](broken://pages/907a98d9c91d9a38396ddcc14d1b90a305f95138)
* [Transactions with Off-chain Signatures](https://ledger-4.gitbook.io/ledger-multisig/guides/transactions-with-off-chain-signatures)
