anomalyco/sst · error

ErrStateNotFound

ErrStateNotFound

Error message

state not found

What it means

ErrStateNotFound is a sentinel error returned by provider.PullState when the backend has no state data for the requested app/stage, and surfaced through Project.Run when the initial workdir state pull finds nothing. Callers (Run in pkg/project/run.go:101) use errors.Is against it to distinguish a brand-new stage from a real backend failure.

Source

Thrown at pkg/project/provider/provider.go:252

	}
	return backend.putData("app", app, stage, bytes.NewReader(data))
}

func PushSnapshot(backend Home, updateID, app, stage string, data []byte) error {
	slog.Info("pushing snapshot", "updateID", updateID)
	err := json.Unmarshal(data, &map[string]interface{}{})
	if err != nil {
		return fmt.Errorf("something has corrupted the state file - refusing to upload: %w", err)
	}
	return backend.putData("snapshot", app, stage+"/"+updateID, bytes.NewReader(data))
}

func PushEventLog(backend Home, updateID, app, stage string, reader io.Reader) error {
	slog.Info("pushing eventlog", "updateID", updateID)
	return backend.putData("eventlog", app, stage+"/"+updateID, reader)
}

var ErrStateNotFound = fmt.Errorf("state not found")

func PullState(backend Home, app, stage string, out string) error {
	slog.Info("pulling state", "app", app, "stage", stage, "out", out)
	reader, err := backend.getData("app", app, stage)
	if err != nil {
		return err
	}
	if reader == nil {
		return ErrStateNotFound
	}
	file, err := os.Create(out)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = io.Copy(file, reader)
	if err != nil {
		return err

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Verify the app and stage names are correct — a typo yields this error because no state exists under that key.
  2. If this is genuinely a new stage, run `deploy` (or `diff`): Run auto-initializes the Pulumi stack in that case (pkg/project/run.go:105).
  3. Confirm you are pointed at the intended backend/home; switching backend locations makes existing state appear missing.
  4. Check the backend storage (app/stage key) actually contains state; if a previous deploy failed mid-push, redeploy to upload state.

Example fix

// before
err := project.Run(ctx, input) // input.Command == "refresh", stage never deployed

// after
err := project.Run(ctx, input)
if errors.Is(err, provider.ErrStateNotFound) {
	input.Command = "deploy" // deploy initializes the stack for a new stage
	err = project.Run(ctx, input)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// No pre-call validation available; optionally probe the backend first:
reader, err := backend.getData("app", app, stage)
hasState := err == nil && reader != nil

Try / catch

err := provider.PullState(backend, app, stage, out)
if errors.Is(err, provider.ErrStateNotFound) {
	log.Printf("no existing state for %s/%s; treating as new stage", app, stage)
	return nil
}
if err != nil {
	return err
}

Prevention

When it happens

Trigger: Calling provider.PullState(backend, app, stage, out) for a stage that has never been deployed (getData returns nil reader), or running `sst Run` with a command other than deploy/diff against a stage with no stored state.

Common situations: Typo in the stage or app name when pulling state; running `sst dev`/non-deploy commands against a stage that was never deployed; pointing at the wrong backend (wrong HOME/home directory or missing SST_STAGE); state was deleted or never uploaded after a first deploy.

Related errors


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