Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Typed Errors and Recovery

Classify policy, setup, grant, lifecycle, process, and network errors with errors.Is and errors.As.

developer

Sandbox errors are part of the control flow. Sentinel values are re-exported by the root package so callers can use errors.Is without importing internal packages. Some failures carry typed details through errors.As. Treat the category as the recovery decision, not the text string.

Common categories

CategoryExamplesUsual response
Profile/configurationErrInvalidProfileFix the profile or route before retrying.
Host capabilityErrSandboxUnavailable, ErrWindowsSetupRequired, ErrWindowsSetupStaleInspect setup status or choose an explicitly acknowledged unconfined policy only when that is acceptable.
AdmissionErrGrantDenied, ErrGrantRequired, ErrExecutorClosed, ErrExecutorSetClosedDo not spawn. Ask the gate or recreate the owner as appropriate.
Grant bindingErrGrantBadMAC, ErrGrantExpired, ErrGrantReplay, ErrGrantWrongCommand, ErrGrantTargetChanged, ErrGrantGuaranteeMismatchDiscard the token and prepare/issue a fresh one after validating the operation.
Process setupErrProcessTTYUnsupported, ErrProcessConPTYUnavailable, ErrOutputLimitChange the request or report a bounded failure. No silent fallback.
NetworkErrEgressRouteDenied, ErrNetworkTargetDeniedKeep the denial visible; a normal process exit does not erase a proxy denial.

Match sentinels and typed details

package example

import (
	"errors"
	"fmt"

	"github.com/looprig/sandbox"
)

func classify(err error) string {
	switch {
	case err == nil:
		return "ok"
	case errors.Is(err, sandbox.ErrGrantRequired):
		return "ask the gate for an approval grant"
	case errors.Is(err, sandbox.ErrGrantReplay):
		return "discard the single-use grant"
	case errors.Is(err, sandbox.ErrNetworkTargetDenied):
		var denied *sandbox.NetworkTargetDeniedError
		if errors.As(err, &denied) {
			return fmt.Sprintf("target denied after exit %d", denied.ExitCode)
		}
		return "network target denied"
	case errors.Is(err, sandbox.ErrSandboxUnavailable):
		return "required OS confinement is unavailable"
	default:
		return err.Error()
	}
}

The returned exit code from a normal process is not an error category. A process can return a non-zero exit with err == nil; a signal, cancellation, or proof failure returns an error and -1. A TargetDeniedError preserves the completed exit code while wrapping ErrNetworkTargetDenied.

Fail closed on ambiguity

If a platform cannot compile a required profile guarantee, NewExecutorSet or For fails. If an exact grant target changes identity, redemption fails. If process-tree zero proof is uncertain, the reservation capsule moves to quarantine for retry rather than releasing authority early. These are deliberate safety outcomes. Retrying the same token or treating an unknown status as success defeats the contract.

Source

Proof

← back to documentation