Mysten Incubation

Error Catalog

Tagged-error unions per plugin, with the discriminator slots and when each tag surfaces.

Every plugin raises tagged errors with a _tag discriminator. Effect.catchTag and Effect.catchTags match on the literal tag string. Most plugins also carry a phase field that identifies which stage of the lifecycle raised, so consumers can pin behavior by tag + phase rather than by message substring.

This catalog enumerates the tags exported from each plugin. The fields shown are the load-bearing discriminator slots; full shapes (and the helper constructors) live in each plugin's errors.ts.

Account

  • AccountAcquireErrorphase: 'validate-name' | 'validate-funding' | 'load-keystore' | 'read-env' | 'decode-inline' | 'bind-signer' | …. Surfaces during account boot.
  • AccountSignErrorphase: 'build-tx' | 'sign' | 'submit' | 'no-digest' | 'await-finality' | 'dependent-package-not-found'. Surfaces when an account-bound sign attempt fails.

Action

  • ActionErrorphase: 'discriminator' | 'build' | 'sign' | 'execute-failed' | 'verify'. Single tag covers all action(...) failure paths.

Coin

  • CoinErrorphase: 'not-found' | 'ambiguous' | 'nested-generic' | 'cap-missing' | 'metadata-fetch' | 'mint-tx'. Surfaces when a coin.fromPackage or coin.known reference cannot be resolved or minted.

DeepBook

  • DeepbookPluginErrorphase: 'image-pull' | 'network' | 'publish' | 'create-pools' | 'pyth-publish' | 'pyth-feed'. Local-mode boot and pool seeding.
  • DeepbookConfigError — invalid deepbook(...) options.
  • ForkIncompatibleError — fork mode rejected an incompatible reference.

Faucet

  • FaucetUnreachable — transport-level (ECONNREFUSED, DNS, TLS, AbortSignal timeout).
  • FaucetExhausted — wall-clock budget exhausted before a funding attempt landed. Carries attempts: number and the underlying lastCause. The attempt-cap exhausting first re-raises the last FaucetUnreachable | FaucetBodyError verbatim — only a wall-clock timeout surfaces as FaucetExhausted.
  • FaucetBodyErrorreason: 'failure-status' | 'invalid-json'. The load-bearing wire invariant: 200 OK with { status: { Failure } } MUST surface here, not as silent success.
  • FaucetConfigError — invalid strategy config.

The "no strategy registered for this chain" case is not a faucet-plugin tag — it surfaces as the substrate StrategyNotFoundError (see Substrate).

Host service

  • HostServiceConfigError — invalid hostService(...) options.
  • HostServiceAcquireErrorphase: 'allocate-port' | 'spawn' | 'ready' | 'exit'. Surfaces during dev-server boot and ready-probing.

Package

  • PublishErrorphase: 'hash' | 'scrub' | 'build' | 'publish-tx' | 'parse' | 'verify'. Single tag covers the full localPackage(...) publish path.

Seal

  • SealErrorphase: 'port-alloc' | 'image' | 'keygen' | 'publish' | 'register' | 'config-render'. Local-keygen boot.
  • SealConfigError — invalid seal(...) options.
  • ForkIncompatibleError — fork-mode reference mismatch.

Sui

  • SuiPluginErrorphase: 'image-build' | 'port-allocate' | 'container-start' | 'rpc-probe' | 'faucet-probe' | 'graphql-probe'. Localnet boot.
  • SuiConfigError — invalid sui(...) options.
  • SuiCliErrorop-tagged failure from a Sui CLI shell-out.
  • ForkUnsupportedError — fork mode rejected an unsupported request.

Wallet

  • WalletBootErrorphase: 'listen' | 'allocate-port' | 'read-token' | 'write-token' | 'bind-account' | 'route-url' | …. Dev-wallet boot.
  • WalletRequestErrorphase: 'origin-missing' | 'origin-forbidden' | 'unauthorized' | 'route-not-found' | 'address-not-found' | 'body-invalid' | …. Per-request rejections inside the running wallet.

Walrus

  • WalrusPluginErrorphase: 'image-build' | 'cluster-network' | 'deploy' | 'exchange' | 'storage-node' | 'proxy'. Local-mode boot.
  • WalrusConfigError — invalid walrus(...) options.
  • ForkIncompatibleError — fork-mode reference mismatch.

Substrate

Errors raised by the shared substrate runtime rather than a single plugin. The one app-facing tag:

  • StrategyNotFoundError — no funding strategy is registered for the requested capability key. Carries capabilityKey and registeredKeys so the renderer can show "I asked for X, only Y is wired". This is what a missing SUI faucet strategy surfaces as — there is no Faucet-prefixed strategy-missing tag.

Catching errors in app code

import { Effect } from 'effect';

const program = someEffect.pipe(
	Effect.catchTags({
		AccountAcquireError: (err) => Effect.logError(`account boot failed at phase ${err.phase}`),
		FaucetExhausted: (err) => Effect.logError(`faucet gave up after ${err.attempts} attempts`),
	}),
);

Plugin-author code that catches its own union should use Effect.catchTag for single-tag handling and catchTags for the multi-tag form; both narrow on the literal _tag discriminator.

On this page