> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> The messages the sauce command and the MCP server print when they stop, what each one means, and what to change.

Find the message or failing stage below, then follow its cause and fix. Quoted messages come from the `sauce` command; `…` marks text that varies with your input.

* If you cannot start the tools, check [installation](#install-and-node) or [MCP setup](#mcp-setup).
* If your program will not compile, check [compile errors](#compile-errors).
* If a chain request fails, check [endpoints and rate limits](#endpoints-and-rate-limits) and [deployment compatibility](#release-not-deployed-and-engine-pairing).
* If execution fails, check [simulation reverts](#simulation-reverts-and---expect-revert), [funding and approvals](#pot-not-deployed-and-approvals), or [wallets and passwords](#wallets-and-passwords).

A failed command exits with a status other than 0:

| Exit | Meaning | What follows the message |
| - | - | - |
| 2 | The command line is wrong: a flag or argument is missing, unknown, malformed or in conflict | ``Run `sauce <command> --help` for usage.`` |
| 1 | Anything else: a program that does not compile, a refusal, a revert, an endpoint error | Nothing |

Each error starts with the command's name, such as `sauce simulate:`. Notes and warnings on stderr do not. With `--json`, a simulation that reverts puts `reverted: true` and `error` first in its JSON.

## Install and Node

The package needs Node.js 24 or newer. `node --version` prints yours.

If your shell does not find `sauce` after `npm install -g @eco-incorp/sauce`, npm's global `bin` directory is not on your `PATH`. `npm prefix -g` prints the prefix that directory is under.

Without a global install, `npx -y @eco-incorp/sauce <command>` runs the command. In a directory whose project does not depend on `@eco-incorp/sauce`, do not run `npx sauce`: npx then fetches an unrelated npm package named `sauce`.

## Compile errors

A compile error names the file, the chain and the line, and often ends with a `hint:`.

### A name nothing declares

```text theme={null}
sauce compile: bad.sauce.ts does not compile for base
…
╰─▶ `recipient` is not a declared variable
    ├╴`recipient` is not a declared variable (bytes 181..190)
    ╰╴error: `recipient` is not a declared variable
       --> bad.sauce.ts:3:17
…
hint: if recipient is a value you supply, make it a parameter of main (`recipient: Uint256`, or `Address`) and pass it with --args
```

The program reads a name that is not a token, a protocol, a local or a parameter. If the value is an input, add it to `main`'s parameters with its type and pass it with `--args`, in the order `main` declares them. If it is a token or protocol, check the spelling with `sauce globals --chain <chain>`.

### A token or contract the chain does not have

```text theme={null}
sauce compile: badtoken.sauce.ts does not compile for base
compileSauceRoute: `FOOBAR` is not a token or protocol on base. …
hint: FOOBAR is not a registered token on base (it has USDC, WETH, 67 stock tokens): take its address as a parameter of main (`token: Address`, passed with --args) and write Token(token).transfer(…)
```

A token symbol compiles only on a chain whose registry records it. Take the token's address as a `main` parameter and write `Token(token).transfer(…)`. See [Names](https://docs.eco.com/sauce/names.md).

A token or contract another chain has is refused at its use, with the file, line and column and the chains that have it:

```text theme={null}
compileSauceRoute: `USDT` is not a token on base. Did you mean `USDC`? A token the chain lacks is zero there, and only a test of it may use it: `if (USDT) { … }` compiles the branch only where the chain has it. It is a token on ethereum, optimism, solana. …
compileSauceRoute: `UniswapV3.Factory` is not deployed on unichain. A contract the chain lacks is zero there, and only a test of it may use it: `if (UniswapV3.Factory) { … }` compiles the branch only where the chain has it. It is deployed on ethereum, optimism, bsc, polygon, monad, arc, base, arbitrum and 2 more.
```

Compile for a chain that has the name, or test the name, `if (USDT) { … }`, so the branch is compiled only where the chain has it ([Names](https://docs.eco.com/sauce/names.md#using-a-name-only-where-the-chain-has-it)).

### A protocol contract that is renamed or ambiguous

```text theme={null}
compileSauceRoute: `CompoundV3.CometUSDC` is not a contract of CompoundV3: it has CUSDCv3, CWETHv3, CUSDTv3.
compileSauceRoute: `Pancakeswap.Factory` is ambiguous under Pancakeswap (pancakeswap-v2, pancakeswap-v3): write `PancakeswapV2.Factory` or `PancakeswapV3.Factory`
```

Use one of the names the message lists. [Protocols](https://docs.eco.com/sauce-sdk/reference/protocols.md) lists every namespace and contract.

### A construct SauceScript does not support

```text theme={null}
╰─▶ 1 unsupported construct(s)
    ╰╴error: a `switch` statement is not supported in SauceScript
       --> badsyntax.sauce.ts:3:3
```

SauceScript is a subset of TypeScript. Rewrite the construct with what the language has: here, `if`/`else`. [Builtins](https://docs.eco.com/sauce/builtins.md) and the language pages list what compiles.

### Using a token write's result

```text theme={null}
`USDC.transfer(...)` returns nothing, so its result cannot be used: a token write has SafeERC20 semantics and reverts the program unless the token accepted it. Call it as a statement.
```

A token write reverts the cook when the token refuses it, so there is no `bool` to check. Call it as a statement.

### A reserved name

```text theme={null}
`__sauce_transfer` is reserved: a token's `.transfer(...)` is lowered to `@sauce/token`'s `transfer`, imported under that name. Rename your `__sauce_transfer`.
```

Rename your function. The same applies to `__sauce_approve` and `__sauce_transferFrom`.

### Signed and unsigned values in one expression

```text theme={null}
╰─▶ cannot combine Int256 and Uint256 in this expression; convert an operand with `Int256(value)` or `Uint256(value)` first (conversions check bounds)
    ╰╴error: …
       --> mixed.sauce.ts:3:10
```

`Int256` and `Uint256` do not mix in arithmetic or comparisons. Convert one operand with `Int256(value)` or `Uint256(value)`. A conversion reverts the cook when the value does not fit the target type.

### A negative constant for an unsigned value

```text theme={null}
╰─▶ constant Int256 value is outside Uint256's range; conversions check bounds, so choose a representable value or a type that includes it
    ╰╴error: …
       --> negunsigned.sauce.ts:3:26
        |
      3 |   const delta: Uint256 = -10;
```

A negative literal is an `Int256`. Declare the value as `Int256`: `const delta: Int256 = -10`.

### An unsupported signed Math helper

```text theme={null}
╰─▶ `Math.…` was removed; use `/` on `Int256` values (`Int256.fromBits(x)` reinterprets a `Uint256`); `Int256.min / -1n` now rejects overflow
╰─▶ `Math.…` was removed; use `<` on `Int256` values
```

The signed `Math` helpers for division, remainder, shift and comparison are removed. The message names the helper you called and the operator that replaces it. Declare the values as `Int256` and use `/`, `%`, `>>`, `<`, `>`, `<=` or `>=`. `Int256.fromBits(x)` reads the bits of a `Uint256` as a signed value.

### A type name used as a variable

```text theme={null}
╰─▶ `Uint256` is a builtin constructor and cannot be bound — constructor calls resolve against the builtin before any binding is consulted, so pick another name
```

`Uint256` and `Int256` are reserved. Rename the local, parameter, constant, import or function.

### An argument of the wrong type

```text theme={null}
sauce tx: --args: argument 1 (recipient: Address): '0x12' is not an address: 20 bytes of 0x-prefixed hex
```

Each `--args` value is checked against `main`'s parameter type before anything is read or built. Give each value in the type its parameter declares. An array or a tuple is JSON (`--args '[1, 2]'`). A negative `Int256` is written as it is: `--args -1`.

```text theme={null}
sauce simulate: --args: main takes 1 argument (value: Int256), got 4
```

Every word after `--` is read as an argument, the flags that follow it included. Put `--` before a value that starts with `--`, and keep `--args` last on the command line when you use it.

## Preview-chain refusals

```text theme={null}
sauce tx: building the cook transaction is refused: it involves optimism (Optimism, chain id 10), a preview chain. The sauce command and its MCP server build and send transactions only on Ethereum, Base, Arc and Solana, and the testnets Arc Testnet, Base Sepolia, Ethereum Sepolia, Solana Devnet and Solana Testnet. On a preview chain they build and send none. A program still compiles there and globals, price, pools and pot's prediction still read; simulate runs wherever the release is deployed on the chain, and says so where it is not.
To ask for Optimism: …
```

The command builds and sends transactions only on Ethereum, Base, Arc and Solana, and the testnets Arc Testnet, Base Sepolia, Ethereum Sepolia, Solana Devnet and Solana Testnet. On every other chain, `compile` and reads work, and `tx`, `run`, `send`, a Pot deployment and `reclaim` are refused before any network read or key use. The second line of the refusal says how to request support for that chain. No flag lifts the refusal. [Chains](https://docs.eco.com/sauce-sdk/reference/chains.md) lists which chains are supported.

Preview status limits building and sending, not simulation: `simulate` runs wherever the release's engine and Kitchen are deployed, Optimism included. Where the engine has no code, `simulate` exits 1 with `the released engine … is not deployed on <chain>: this SDK's cook cannot run there` (see [Release not deployed](#release-not-deployed-and-engine-pairing)).

## Endpoints and rate limits

A command that reads a chain through a built-in public endpoint prints this on stderr:

```text theme={null}
base: read through a built-in public endpoint, which can be slow or rate-limited; give your own with --rpc-url <url> or --config <file>
```

Public endpoints can be slow, rate-limited or unavailable. The command moves to another built-in endpoint for that chain when one fails. For dependable reads, give your own endpoint. See [Chains and endpoints](https://docs.eco.com/sauce-sdk/cli/chains-and-endpoints.md).

| Message | Cause | Fix |
| - | - | - |
| `missing --rpc-url <url> (or --config <file>): the kava endpoint, which has no built-in public one` | The chain has no built-in endpoint | Pass `--rpc-url <url>`, or a `--config` file with the chain's id |
| `--offline reads no chain, and this reads base` | `--offline` blocks every read, and the command needs one | Remove `--offline` |
| `missing --value <wei>: the cook pays the Kitchen's execution fee plus any native the program spends. Pass it, or an RPC endpoint (--rpc-url or --config) to read the fee.` | `sauce tx --offline` cannot read the Kitchen's fee | Pass `--value <wei>`, or remove `--offline` |
| `--config rpc.json: rpcUrls["8453"] is not a URL; replace the placeholder` | The config file still holds a placeholder | Put the endpoint's URL in its place, or remove the entry to use the built-in endpoint |
| `the RPC endpoint serves chain 1, but base is 8453` | The endpoint is for a different chain than `--chain` | Use the endpoint for that chain, or key each endpoint by its chain id in `--config` |
| `reading the chain id failed: HTTP request failed.` | The endpoint did not answer | Check the URL, or use another endpoint |

A simulation through an endpoint that does not serve `eth_simulateV1` falls back to `eth_call`. It still reports the result and the gas, but no transfers, and the output names the method it used.

## Simulation reverts and `--expect-revert`

```text theme={null}
The cook reverts: the program threw "not enough USDC"
```

`sauce simulate` exits 1 when the cook reverts. The first line gives the decoded reason. Here a `require` in the program failed because the Pot holds less USDC than the program spends. To simulate with a balance the Pot does not hold yet, pass `--assume-balance USDC:2`. To pull the tokens from your wallet in the same cook, pass `--fund USDC:2`. See [Funding](https://docs.eco.com/sauce-sdk/cli/funding.md).

`--expect-revert <text>` checks that the cook reverts. The command exits 0 only when the revert reason contains the text:

```text theme={null}
As expected, the cook reverts: the program threw "not enough USDC"
```

In every other case it exits 1, and the first line says what happened:

```text theme={null}
Expected a revert with "too much", but the cook reverts: the program threw "not enough USDC"
Expected a revert with "not enough", but the cook succeeds
```

Check the text you passed against the `require` message in your program. The text matches any part of the reason.

### A revert with no data

```text theme={null}
The cook reverts: it reverted with no data (out of gas, or a revert with no reason)
```

A checked operation failed with no message. Among the causes are a conversion of a value outside the target type, such as `Uint256(value)` of a negative `Int256`, and unsigned negation of a nonzero value, such as `-amount` with `amount: Uint256`. Write `-Int256(amount)` for a signed result. Before a conversion that can fail, add a `require` with a message, so the revert names the condition:

```ts convert.sauce.ts theme={null}
// Converts a signed value to unsigned, refusing a negative one with a message.
// Run: sauce simulate convert.sauce.ts --chain base --owner <owner> --args <value>
//   value: Int256, the signed value
function main(value: Int256): Uint256 {
  require(value >= 0, "negative value");
  return Uint256(value);
}
```

## Release not deployed, and engine pairing

`sauce pot` reports whether the release's engine and Kitchen have code on the chain it reads. Where the engine has none, it says so:

```text theme={null}
The released engine has no code on base: a cook there has nothing to run on.
```

A cook needs the release's engine on its chain. Run cooks on a chain where `sauce pot --chain <chain> --owner <address>` reports the engine as deployed. Where the Kitchen has no code, commands that read its fee or deploy a Pot refuse:

```text theme={null}
the Kitchen … has no code on …: the released Sauce contracts are not deployed there
```

Programs from the pinned compiler run only on the engines its release set records. A TypeScript builder that names an engine, such as `v12Pot.encodeCook`, checks the pairing and throws for an engine that the release sets record only for other compilers:

```text theme={null}
<engine address> is <engine release> <version>, which runs compiler <version> output; this program is compiler <version>'s. Compiler <version> output runs on <engine release> <version> (<engine address>).
```

Build the cook for the engine the message names: the release addresses come from `v12EngineAddress()`.

## Pot not deployed and approvals

On an EVM chain, an owner's Pot is deployed by a transaction of its own, before its first cook. With an endpoint, when the Pot has no code yet, `sauce tx` prints two transactions and explains on stderr:

```text theme={null}
Your Pot … on base isn't deployed yet: the first transaction deploys it (any account may send it; the Pot is the owner's either way), and the cook comes last. Send them in order, then fund the Pot with what the program spends.
```

Send the deployment first, and let it land. If the program spends what the Pot holds, fund the deployed Pot before you send the cook, even though the note lists the funding last. Do not send tokens to the address before the deployment: an undeployed address is only the Kitchen's prediction ([Funding a Pot](https://docs.eco.com/sauce-sdk/cli/funding.md)). With an endpoint, `--fund` plans a token's transfer between the deployment and the cook, and that note then ends at "Send them in order." `ETH:<amount>` adds to the cook's value instead, with no separate transfer. Without an endpoint, the plan checks no deployment and includes no deployment step: deploy the Pot first. A signer estimates the cook's gas too low while the Pot has no code. Use the `gas` that `sauce tx` prints, or build the cook again after the deployment lands.

`sauce run` sends the deployment only after you approve it. With no terminal to ask on, or with `--json`, it stops:

```text theme={null}
sauce run: nothing was sent: this run needs an approval, and there is no terminal to ask on:
  deploy Pot …
Pass --yes (-y) to approve them (and --password-file with a keystore).
```

Pass `--yes` together with a password source that does not prompt.

| Message | Cause | Fix |
| - | - | - |
| `--value 1 is below the Kitchen's execution fee on base, … wei (… ETH): the cook would revert with FeeNotPaid` | The cook's value is below the Kitchen's fee | Remove `--value` to have the fee read, or pass at least the fee plus the native the program spends |
| `the released Kitchen … has no code on …: no Pot can be deployed there, so nothing was sent` | The chain has no released Kitchen | Use a chain where `sauce pot` reports the Kitchen as deployed |
| `0x… holds 0 of USDC (base units), below the 1000000 --fund USDC:1 needs` | The wallet holds less than `--fund` pulls | Fund the wallet, or lower the amount |
| `USDC is not approved to Permit2: approve it, or pass --yes (-y) to let the run do it` | `--fund` in its default Permit2 mode needs the token approved to Permit2 first | Pass `--yes` to send the approval, or approve it yourself. From a wallet whose policy limits the token, the approval is refused: use `--fund-mode permit`, `allowance` or `transfer` |
| `the Kitchen … puts the Pot of owner … and salt … at …, but this SDK has it at …: this SDK does not match the deployed Kitchen …` | The chain's Kitchen puts a Pot not deployed yet at another address than this SDK derives, so a cook built here would reach no Pot ([The Pot guard](https://docs.eco.com/sauce-sdk/cli/pot.md#the-pot-guard)) | Nothing was simulated, built or sent. Where the message says the Kitchen is newer than this SDK, run `sauce update` |
| `… is a Pot of compiler … (v12-evm …, kitchen-evm …), which @eco-incorp/sauce … pair with …` | The Pot was minted under a Kitchen whose engine runs no program this SDK compiles | Cook on a Pot the paired Kitchen created |
| `Kitchen.deployPot reverts for the owner 0x0000000000000000000000000000000000000000: a Pot with no owner is a Shared Pot, which Kitchen.deploySharedPot(salt) deploys. Nothing was simulated, built or sent.` | `--owner` is the zero address | Name the Pot's owner. The command exits `2`, offline too |
| `nothing was sent — transaction 2 of 2 (cook on Pot 0x…): …` | `sauce send`'s wording: one step of the batch fails the Pot guard, so nothing is sent. `sauce run` and a wallet's send refuse the same plans before any step is sent, with their own step labels | Fix the step the message names, then send the batch again |
| `The Pot's address is NOT checked against the deployed Kitchen: no RPC endpoint was given.` | `--offline` reads no Kitchen | A note, not an error: check the address with an endpoint before you fund it |

With `--fund-mode allowance`, the run approves the Pot in a transaction of its own and warns:

```text theme={null}
warning: the Pot's allowance over your USDC was set in a transaction of its own, and stands until a cook spends it — for good if this one does not. --fund-mode permit2 (the default) gives the Pot no allowance at all.
```

A cook that reverts rolls back its own steps. It does not undo an approval that an earlier transaction made. Use the default Permit2 mode, or approve exactly the amount the cook spends.

## Wallets and passwords

| Message | Cause | Fix |
| - | - | - |
| `missing a signer: --wallet <name>, --keystore <path> (each with a password source, or a prompt) or --private-key <hex>` | A command that sends was given no key | Create a wallet with `sauce wallet new <name>`, and pass `--wallet <name>` |
| `missing a signer: --wallet <name> (a Solana wallet) or --keypair <path>` | The same, on Solana | Pass a Solana wallet or `--keypair` |
| ``no wallet nobody in ./wallets: `sauce wallet list` names them, and `sauce wallet new nobody` creates one`` | No wallet has that name in the wallet directory | Run `sauce wallet list`, or check `--wallets` |
| `wallet ops-sol is a Solana wallet: an EVM transaction is signed by an EVM wallet` | The wallet's kind does not match the chain | Use an EVM wallet on Ethereum, Base, Arc and the EVM testnets, and a `--solana` wallet on Solana, Solana Devnet and Solana Testnet |
| `the keystore password is wrong (the keystore's MAC does not match)` | The password does not decrypt the wallet | Check the source you named. A file or command loses one trailing newline only |

### Password sources

A password comes from exactly one source: `--password-env`, `--password-file`, `--password-command`, or a prompt.

| Message | Cause | Fix |
| - | - | - |
| `give one password source, not --password-env and --password-file` | Two sources were given | Keep one |
| `--password-env takes the NAME of an environment variable (letters, digits and _), not its value` | The password itself was passed | Pass the variable's name |
| `no terminal to ask for the password on: pass --password-env <NAME>, --password-file <path> or --password-command <command>` | A command that signs was given no password source and runs with no terminal, as in CI or a pipe. It exits 2 | Name one of the three sources |
| `--password-env SAUCE_PW: the variable is not set` | The variable is not in the command's environment | Export it in the shell that runs `sauce` |
| `--password-command exited with status 3; its output is not shown` | The command failed | Run the command yourself to see why |
| `--password-file pw.txt gives a password of under 8 characters: a wallet's password protects its key on disk, so use a longer one` | A new wallet's password is shorter than 8 characters | Use a longer password |

### A password file others can read

```text theme={null}
sauce wallet new: --password-file pw-open.txt can be read or written by others (mode 644): a password file must be yours alone. Run `chmod 600 pw-open.txt`, then try again
```

Run the `chmod 600` the message names. The wallet directory gets a warning of its own when others can list it:

```text theme={null}
warning: ./wallets is open to others (mode 755): each wallet file is yours alone, but `chmod 700 ./wallets` keeps their names private too
```

### Wallet policies

A wallet's policy is `<name>.policy.json` beside the wallet. Before each send, the command simulates the transaction to measure what it moves, then holds the result to the policy's limits. A policy file that others can write is refused when the wallet sends, and `sauce wallet list` warns about it:

```text theme={null}
warning: wallets/ops.policy.json can be written by others (mode 666), who could loosen it: `chmod 600 wallets/ops.policy.json`
```

A field the policy does not define is an error. The fields are `chains`, `to`, `native` and `tokens`:

```text theme={null}
warning: wallets/ops.policy.json: maxGas is not a policy field (chains, to, native, tokens)
```

A send that breaks a limit is refused before it is signed:

```text theme={null}
refused by the policy of wallet <name> (<path>): <reason>
```

For example, with `"chains": ["ethereum"]` and a run on Base:

```text theme={null}
sauce run: refused by the policy of wallet ops (wallets/ops.policy.json): chains allows ethereum, and this transaction is on base
```

The reason names the limit:

| Reason begins | Limit |
| - | - |
| `chains allows …, and this transaction is on …` | `chains` |
| `to allows … address(es), and this transaction goes to …` | `to` |
| `to allows … address(es), and this transaction deploys the wallet's Pot …` | `to`: add the Pot, which cooking on it needs |
| `tokens.USDC.perTransaction is …, and this transaction sends …` | A per-transaction limit |
| `tokens.USDC.perDay is …; … went in the last 24 hours, and this transaction sends …` | A 24-hour limit, counted from the wallet's ledger |
| `native is limited, and …` or `tokens.USDC is limited, and …` | The transaction's movements, or an allowance it leaves, could not be measured, for example through an endpoint without `eth_simulateV1` |
| `this transaction approves Permit2 (…) for USDC, …, and tokens.USDC limits it` | `tokens`: an approval of Permit2 for a limited token, which would make every Permit2 allowance of it given before spendable again |

Send less, use an endpoint that serves `eth_simulateV1`, or change the policy if the limit is wrong. From a wallet whose policy limits a token, fund it with `--fund-mode permit`, `allowance` or `transfer`, not through Permit2. See [Wallets and policy](https://docs.eco.com/sauce-sdk/cli/wallets-and-policy.md).

## Solana

### Execution fee

The Kitchen charges an execution fee in lamports on every cook. `--max-execution-fee` caps it:

```text theme={null}
sauce tx: the execution fee is 85672 lamports, above --max-execution-fee 1: nothing was signed or sent
```

The Kitchen's owner sets the fee. If the fee is acceptable, raise the cap. A cook states the most fee it pays, read when the cook is built. If the fee rises above that before the cook lands, the cook fails with this reason:

```text theme={null}
the execution fee is above the max_execution_fee the cook signed (it rose since it was read): run it again
```

### Lamports and rent

The owner pays the Kitchen's fee, rent for every new account (the Pot, token accounts, a code buffer, a lookup table) and the transaction fees. Solana's `simulateTransaction` takes no balance overrides, so the owner must hold these lamports for a simulation too:

```text theme={null}
… holds … lamports, and the cook takes …: … in rent for the Pot, the execution fee of … and the transaction's. Solana's simulateTransaction takes no balance overrides, so the owner must hold them for a simulation too
```

Other lamport failures read `the fee payer holds less than the execution fee`, or end with `which the transaction would leave below its rent-exempt minimum`. Send the owner more SOL. `sauce reclaim` lists the code buffers and lookup tables an owner left open, and closes them to return their rent.

### Accounts and transaction size

A Solana transaction holds at most 1232 bytes. `sauce run` stages a large program in a code buffer and puts the cook's accounts in an address lookup table. Some cooks are still too large:

```text theme={null}
the cook names … accounts, more than one lookup table holds (…)
the staged cook is a …-byte transaction even with every account it names in a lookup table, past Solana's 1232: it signs or calls too many
```

Make the cook smaller: fewer pools, fewer accounts, or two programs instead of one. `sauce compile --json` reports the cook's size against the limit before you run it. See [Solana](https://docs.eco.com/sauce-sdk/cli/solana.md).

### Compute units

```text theme={null}
The cook runs out of compute units with every pool's stop worked out three times, the venues given … units at the last: offer fewer pools, or a tighter priceLimit, and simulate again
```

The swaps in the cook need more than the transaction's compute budget. Offer fewer pools or a tighter `priceLimit`, then simulate again.

### No `try`/`catch` on Solana

```text theme={null}
╰─▶ `try/catch` is not available on the svm target
```

A Solana program cannot catch a failure: any failure reverts the cook. Check the conditions first with `require`, or split the work into separate cooks.

## MCP setup

### Runtime packages

`sauce mcp` loads the MCP SDK and `zod`, and a Solana simulation in a local copy loads LiteSVM. These are optional peer dependencies of the package. When neither your own copies nor the runtime folder has them, the first use installs the folder. The command refuses where it cannot install:

```text theme={null}
the MCP server needs @modelcontextprotocol/sdk … and zod …, not installed for this sauce yet, and --offline installs nothing: run `sauce runtime install`
```

Run `sauce runtime install`, then `sauce runtime` to see where each package comes from. The runtime folder must belong to you alone. Otherwise the command refuses to load it:

```text theme={null}
… is open to … (mode …): sauce loads code only from a runtime folder that is yours alone. Run chmod 700 …
```

### A desktop client does not find `sauce`

A desktop client (Claude Desktop, for example) may not see your shell's `PATH`, so it cannot start a `sauce` installed under nvm or another version manager. `sauce` starts with `#!/usr/bin/env node`, so an absolute path to `sauce` alone fails with `env: node: No such file or directory`. In the client's configuration, set the command to the absolute path that `which node` prints, and the args to the path that `which sauce` prints, then `mcp`:

```json theme={null}
{
  "mcpServers": {
    "sauce": { "command": "/absolute/path/to/node", "args": ["/absolute/path/to/sauce", "mcp"] }
  }
}
```

Setting the command to `npx` with args `["-y", "@eco-incorp/sauce", "mcp"]` needs Node on the client's `PATH` too, because `npx` is a Node.js script.

### `sauce mcp setup` stops at a file

```text theme={null}
sauce mcp: .cursor/mcp.json is not plain JSON (a comment in it, perhaps), so setup leaves it alone: add "sauce": {…} under "mcpServers" yourself
```

`setup` refuses a JSON file it cannot parse and exits `2`. The files for the agents before it are already written, and those after it are not. Add the entry the message prints to that file by hand, then run `setup` again with `--agent` naming the agents after it. See [`sauce mcp setup`](https://docs.eco.com/sauce-sdk/cli/mcp#sauce-mcp-setup).

### Wallet tools over HTTP

```text theme={null}
sauce mcp: --wallets is for stdio: the HTTP server never signs, and serves no wallet tools
```

The HTTP server serves no wallet tools. Serve wallets over stdio, the transport a coding agent launches. See [MCP wallets](https://docs.eco.com/sauce-sdk/mcp/wallets.md).

### A project entry pinned to a different version

`sauce mcp setup` writes `npx -y @eco-incorp/sauce@<version> mcp` into each agent's project file. To use the latest package, run `npx -y @eco-incorp/sauce@latest mcp setup --force` to rewrite the entry, then restart the agent's session.

## Next steps

* [Production checklist](https://docs.eco.com/sauce-sdk/operating/production-checklist.md)
* [Package updates](https://docs.eco.com/sauce-sdk/operating/upgrading.md)
* [CLI overview](https://docs.eco.com/sauce-sdk/cli/overview.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.