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:
export PACT_MAINNET_ENABLED=1Intentional — 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.
unset PACT_CLUSTER # orexport PACT_CLUSTER=mainnetneeds_funding
Section titled “needs_funding”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:
- Empty ATA. Transfer mainnet USDC into the ATA shown by
pact balance --json(body.ata). The CLI never moves USDC. - No allowance. Run
pact approve <usdc>. - Insufficient allowance. Run
pact approve <higher-usdc>to replace the existing delegation.
auto_deposit_capped
Section titled “auto_deposit_capped”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.
no_provider
Section titled “no_provider”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.jsonto force a refetch on next call. - Uncurated provider. Use
--rawfor a non-covered call (the CLI signs and forwards without slug rewriting), or fall back topact pay <tool> <url>for any 402-gated endpoint.
pact --raw --json https://your.host/pathdiscovery_unreachable
Section titled “discovery_unreachable”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--gatewayorPACT_GATEWAY_URL). - Check Status for an incident.
endpoint_paused
Section titled “endpoint_paused”Slug exists but the provider is paused. Pick another or retry later; Status reflects the same state.
signature_rejected
Section titled “signature_rejected”Signature timestamp outside the skew window. Sync your clock:
# macOSsudo sntp -sS time.apple.com
# Linux (systemd-timesyncd)sudo timedatectl set-ntp trueThen retry the request.
needs_project_name (exit 40)
Section titled “needs_project_name (exit 40)”Couldn’t resolve a project name from --project, $PACT_PROJECT, the
git repo, or the cwd basename.
pact --project my-agent balance --json# orexport PACT_PROJECT=my-agentcli_internal_error (exit 99)
Section titled “cli_internal_error (exit 99)”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:
- Upgrade:
npm i -g @q3labs/pact-cli@latest(≥0.3.0). - Confirm pay.sh is funded:
pay account list(active),pay account balance(non-zero). - 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:
- Local. Install pay.sh and run
pay setuponce — writes~/.config/pay/accounts.ymland provisions a keypair. Re-runpact pay. - CI. Export a base58 64-byte secret as
PACT_PRIVATE_KEY.
pact pay failure modes
Section titled “pact pay failure modes”Transparent on success. On failure: client_error envelope with
structured body.error:
body.error | Meaning | Fix |
|---|---|---|
unsupported_tool | tool isn’t curl | pact pay wraps curl only in v1 |
tool_missing | curl isn’t installed | install via your package manager |
unknown_402 | 402 had no recognized x402 / MPP challenge | check the upstream’s payment flow docs |
payment_rejected | server rejected the signed retry header | check body.reason for the gateway’s verdict |
no_supported_network | server only offered networks the CLI doesn’t speak | upstream needs to advertise solana / solana-devnet |
session_challenge_unsupported | MPP intent=session challenge | not 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:
- Try a different x402 endpoint (
stablecrypto.devis the reference test endpoint). If it succeeds, the original upstream is at fault. - Sync your clock and retry — challenge windows are usually 30–60s.
- If it persists across endpoints, capture the
[pact]stderr block plus the upstream challenge headers and file an issue.
Resetting state
Section titled “Resetting state”Start fresh:
# Per-project state — wallet, policy, cacherm -rf ~/.config/pact/<project>/
# Just the discovery cacherm ~/.config/pact/<project>/endpoints-cache.jsonStill stuck?
Section titled “Still stuck?”- Commands — exact envelope shapes for every subcommand.
- Operations → Private beta — access, rate limits, and contact for the private-beta team.
- Operations → Status — gateway and settler health.