anomalyco/sst · error

ErrStageNotFound

ErrStageNotFound

Error message

stage not found

What it means

ErrStageNotFound is returned by Project.Run when the backend has no state for the app/stage and the requested command cannot operate on a nonexistent stage. Only `deploy` and `diff` may implicitly initialize a new stack; any other command on a stage with no state returns this sentinel (pkg/project/run.go:102-103).

Source

Thrown at pkg/project/stack.go:118

	New   interface{}
}

type StackCommandEvent struct {
	App     string
	Stage   string
	Config  string
	Command string
	Version string
}

type Error struct {
	Message string   `json:"message"`
	URN     string   `json:"urn"`
	Help    []string `json:"help"`
}

var ErrStackRunFailed = fmt.Errorf("stack run had errors")
var ErrStageNotFound = fmt.Errorf("stage not found")
var ErrPassphraseInvalid = fmt.Errorf("passphrase invalid")
var ErrProtectedStage = fmt.Errorf("cannot remove protected stage")
var ErrProtectedDevStage = fmt.Errorf("cannot run sst dev on protected stage")
var ErrPolicyViolation = fmt.Errorf("policy violations detected")
var ErrPolicyConfigError = fmt.Errorf("policy configuration error")

func (p *Project) ResolvePolicyPackPath(policyPath string) (string, error) {
	var resolvedPath string
	if filepath.IsAbs(policyPath) {
		resolvedPath = policyPath
	} else {
		resolvedPath = filepath.Join(p.PathRoot(), policyPath)
	}

	if _, err := os.Stat(resolvedPath); err != nil {
		return "", fmt.Errorf("Policy pack not found in path: %v", resolvedPath)
	}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Check the stage name and SST_STAGE env for typos; confirm the stage was previously deployed (`sst deploy` at least once).
  2. If the stage should exist, verify you're using the same backend/home as the original deploy.
  3. If the stage is intentionally new, run `deploy` first so the stack is initialized before other commands.
  4. Skip destroy/refresh steps in pipelines for stages that don't exist yet (guard with a state existence check).

Example fix

// before
input := stack.RunInput{Command: "destroy", Stage: "prod"} // stage never deployed
err := project.Run(ctx, input)

// after
err := project.Run(ctx, stack.RunInput{Command: "diff", Stage: "prod"})
if errors.Is(err, stack.ErrStageNotFound) {
	log.Printf("stage prod does not exist; nothing to destroy")
	return nil
}
err = project.Run(ctx, input)
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe whether the stage has state before running non-deploy commands:
err := project.Run(ctx, stack.RunInput{Command: "diff", Stage: stage})
stageExists := !errors.Is(err, stack.ErrStageNotFound)

Try / catch

err := project.Run(ctx, input)
if errors.Is(err, stack.ErrStageNotFound) {
	log.Printf("stage %s has no state; skipping %s", input.Stage, input.Command)
	return nil
}

Prevention

When it happens

Trigger: Calling Run with command values like `refresh`, `destroy`, `dev`, etc. against a stage that has never been deployed (underlying Pull returned provider.ErrStateNotFound).

Common situations: Running `sst destroy` or `sst refresh` on a stage name that was never deployed (typo or wrong SST_STAGE env); CI deploying to a new stage while a later pipeline step runs a non-deploy command before the first deploy finished; operating on the wrong backend where the stage's state doesn't exist.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/e3f634862b2d0a2f. Report an issue: GitHub.