Skip to content

Troubleshooting

Most “this doesn’t work” reports trace back to: the closed-beta gate (PACT_MAINNET_ENABLED=1) unset, the wallet not on the allowlist, or the ATA unfunded. This page covers those plus every other CLI failure mode. Match the status field on the envelope to a section below.

client_error with PACT_MAINNET_ENABLED in the message

Section titled “client_error with PACT_MAINNET_ENABLED in the message”

The closed-beta gate is unset. On-chain commands short-circuit until:

Terminal window
export PACT_MAINNET_ENABLED=1

Intentional — the CLI routes real USDC; the gate stops first-invocation accidents.

client_error with PACT_CLUSTER in the message

Section titled “client_error with PACT_CLUSTER in the message”

PACT_CLUSTER set to something other than mainnet. The CLI rejects unsupported values at startup; v1 is mainnet-only.

Terminal window
unset PACT_CLUSTER # or
export PACT_CLUSTER=mainnet

ATA balance below the estimated premium, or no allowance granted to SettlementAuthority. The body tells you which:

{
"status": "needs_funding",
"body": {
"wallet": "<base58>",
"needed_usdc": 0.0001,
"current_balance_usdc": 0,
"deposit_url": "https://dashboard.pactnetwork.io/agents/<base58>"
}
}

Remediation:

  1. Empty ATA. Transfer mainnet USDC into the ATA shown by pact balance --json (body.ata). The CLI never moves USDC.
  2. No allowance. Run pact approve <usdc>.
  3. Insufficient allowance. Run pact approve <higher-usdc> to replace the existing delegation.

The requested approval exceeds either per_deposit_max_usdc or session_total_max_usdc in ~/.config/pact/<project>/policy.yaml.

{
"status": "auto_deposit_capped",
"body": {
"reason": "session_total_exceeded",
"session_used_usdc": 9,
"session_max_usdc": 10,
"per_deposit_max_usdc": 5,
"suggest": "raise cap in ~/.config/pact/<project>/policy.yaml or run pact approve manually"
}
}

Edit policy.yaml to raise the cap, or run pact approve with a value that fits.

Hostname isn’t in the discovery cache — either uncurated provider or stale local cache.

  • Curated provider. Wait for the cache to refresh, or remove ~/.config/pact/<project>/endpoints-cache.json to force a refetch on next call.
  • Uncurated provider. Use --raw for a non-covered call (the CLI signs and forwards without slug rewriting), or fall back to pact pay <tool> <url> for any 402-gated endpoint.
Terminal window
pact --raw --json https://your.host/path

Gateway URL unreachable or returned non-2xx on discovery. Body includes URL + underlying error.

  • Confirm the gateway URL (default https://api.pactnetwork.io; override with --gateway or PACT_GATEWAY_URL).
  • Check Status for an incident.

Slug exists but the provider is paused. Pick another or retry later; Status reflects the same state.

Signature timestamp outside the skew window. Sync your clock:

Terminal window
# macOS
sudo sntp -sS time.apple.com
# Linux (systemd-timesyncd)
sudo timedatectl set-ntp true

Then retry the request.

Couldn’t resolve a project name from --project, $PACT_PROJECT, the git repo, or the cwd basename.

Terminal window
pact --project my-agent balance --json
# or
export PACT_PROJECT=my-agent

Unexpected error inside the CLI. The body includes the error message but not a stack trace by design. File an issue with the exact command and the envelope output.

cli_internal_error: Attempt to debit an account but found no record of a prior credit

Section titled “cli_internal_error: Attempt to debit an account but found no record of a prior credit”

The v0.2.x two-wallet bug: pact approve signed with an unfunded pact-managed keypair while pay.sh held the USDC. Fixed in v0.3.0 — pact approve now signs with pay.sh’s active account.

If you still see this:

  1. Upgrade: npm i -g @q3labs/pact-cli@latest (≥0.3.0).
  2. Confirm pay.sh is funded: pay account list (active), pay account balance (non-zero).
  3. Retry pact approve <usdc>.

[pact] coverage skipped: no wallet — set up pay or PACT_PRIVATE_KEY

Section titled “[pact] coverage skipped: no wallet — set up pay or PACT_PRIVATE_KEY”

Neither pay.sh nor PACT_PRIVATE_KEY resolved to a usable keypair. The wrapped tool still ran; only the Pact coverage leg was skipped.

Fixes:

  1. Local. Install pay.sh and run pay setup once — writes ~/.config/pay/accounts.yml and provisions a keypair. Re-run pact pay.
  2. CI. Export a base58 64-byte secret as PACT_PRIVATE_KEY.

Transparent on success. On failure: client_error envelope with structured body.error:

body.errorMeaningFix
unsupported_tooltool isn’t curlpact pay wraps curl only in v1
tool_missingcurl isn’t installedinstall via your package manager
unknown_402402 had no recognized x402 / MPP challengecheck the upstream’s payment flow docs
payment_rejectedserver rejected the signed retry headercheck body.reason for the gateway’s verdict
no_supported_networkserver only offered networks the CLI doesn’t speakupstream needs to advertise solana / solana-devnet
session_challenge_unsupportedMPP intent=session challengenot supported in v1

pact pay: server returned 402 again after payment

Section titled “pact pay: server returned 402 again after payment”

pact pay signed the retry and the upstream returned 402 anyway. Almost always upstream-side (clock skew, nonce reuse, expired challenge) — the merchant rejected an otherwise-valid payment.

To isolate:

  1. Try a different x402 endpoint (stablecrypto.dev is the reference test endpoint). If it succeeds, the original upstream is at fault.
  2. Sync your clock and retry — challenge windows are usually 30–60s.
  3. If it persists across endpoints, capture the [pact] stderr block plus the upstream challenge headers and file an issue.

Start fresh:

Terminal window
# Per-project state — wallet, policy, cache
rm -rf ~/.config/pact/<project>/
# Just the discovery cache
rm ~/.config/pact/<project>/endpoints-cache.json