Errors
Recover from errors in development and production
Introduction
The ecosystem of packages based on Kit's error system benefit from strongly typed error data, and descriptive error messages. Its error messages get scrubbed from your production bundles, which means that the library of error messages can grow indefinitely without adding a single byte to your app.
Installation
Errors are included within the @solana/kit library but you may also install them using their standalone package.
What is a SolanaError?
A SolanaError is a class made of three components:
- An error code; found in the union named
SolanaErrorCode - An error message
- Optional error context
Here's an example of some code that responds to various errors, taking advantage of the error context offered by each one:
Catching errors
When you encounter an error, you can determine whether it is a SolanaError or not using the isSolanaError() function:
When you have a strategy for handling a particular error, you can supply that error's code as the second argument. This will both identify that error by code and refine the type of the SolanaError such that the shape of its context property becomes known to TypeScript.
Some Solana errors have, as their root cause, another Solana error. One such example is during transaction simulation (preflight):
Failed transaction errors
When a transaction fails to send, Kit raises one of two high-level error codes that wrap whatever actually went wrong with extra context useful for debugging.
SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION
This is the error you get back when sending a single transaction fails. The message itself indicates whether the failure happened during preflight or after the transaction was submitted; the context exposes the underlying error, simulation logs, the preflight result when available, and the full TransactionPlanResult for deeper inspection.
The full TransactionPlanResult is also attached as error.context.transactionPlanResult, but it is non-enumerable so it does not pollute serialized errors. Cast it to TransactionPlanResult when you need to walk the tree.
SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS
The plural variant is raised when sending more than one transaction fails. Its context exposes a failedTransactions array — one entry per failure, with the underlying error, its position in the plan, simulation logs, and preflight data — plus the same non-enumerable transactionPlanResult.
Each individual error in the array has already been unwrapped from any preflight wrapper, so you can branch on its code directly the same way you would for a standalone SolanaError.
Walking transaction plan results
Both failed-transaction errors above expose a transactionPlanResult you can inspect, and any successful multi-transaction send returns one directly. A TransactionPlanResult is a tree that mirrors the original plan, with one of three statuses at each leaf — successful, failed, or canceled. Kit ships a small set of helpers for working with these trees without writing your own recursion.
flattenTransactionPlanResult collapses the tree into an array of leaf results, in the order they appear:
summarizeTransactionPlanResult bucketizes the leaves into successful, failed, and canceled arrays, plus a single successful boolean for the overall outcome:
getFirstFailedSingleTransactionPlanResult is a convenience for when you only care about the first failure in a tree — useful for surfacing a single root cause in error UI:
By default, executors throw SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN on any failure. If you would rather inspect a partial result without a try/catch, passthroughFailedTransactionPlanExecution catches that error and returns the embedded TransactionPlanResult instead.
Program-specific errors
Codama-generated program packages export their own error helpers so you can identify and format program-specific failures. The pattern is consistent across packages: an isXError(error, transactionMessage) type guard, a getXErrorMessage(code) formatter, and an enum-shaped XError for individual codes (where X is the program name, e.g. System for @solana-program/system).
When sending a transaction or transaction plan, the program-specific error usually lives a few hops down the chain — typically as the cause of SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION or as one of the failedTransactions[i].error entries on the plural variant. Pair the helpers above with the failed-transaction errors documented earlier to surface actionable error messages to your users.
Error messages
In development mode
When your bundler sets the constant __DEV__ to true, every error message will be included in the bundle. As such, you will be able to read them in plain language wherever they appear.
The size of your JavaScript bundle will increase significantly with the inclusion of every error
message in development mode. Be sure to build your bundle with __DEV__ set to false when you
go to production.
In production mode
When your bundler sets the constant __DEV__ to false, error messages will be stripped from the bundle to save space. Only the error code will appear in the message when an error is encountered. Follow the instructions in the error message to convert the error code back to the human-readable error message.
For instance, to recover the error text for the error with code 7050005: