anomalyco/sst · error

ErrProtectedDevStage

ErrProtectedDevStage

Error message

cannot run sst dev on protected stage

What it means

ErrProtectedDevStage is the sentinel error for attempts to run `sst dev` against a stage marked as protected. It is declared alongside the other stage-protection sentinels in pkg/project/stack.go to prevent live dev sessions from mutating protected (usually production) infrastructure.

Source

Thrown at pkg/project/stack.go:121

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)
	}

	return resolvedPath, nil
}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Run dev against a personal stage: `sst dev --stage myname` instead of the protected stage.
  2. Check for an SST_STAGE environment variable or CI config forcing the protected stage name and unset/override it.
  3. If you genuinely need to debug the protected stage, use `sst diff` or read-only commands, or have an admin temporarily disable protect.

Example fix

// before
sst dev --stage prod
// after
sst dev --stage myname
Defensive patterns

Strategy: validation

Validate before calling

// Check which stage dev will use before launching
const stage = process.env.SST_STAGE ?? "";
const PROTECTED = ["prod", "production", "staging"];
if (PROTECTED.includes(stage)) {
  console.error(`Refusing to run dev on protected stage '${stage}'`);
  process.exit(1);
}

Type guard

const isProtected = (stage: string, protectedList: string[]) =>
  protectedList.includes(stage.toLowerCase());

Prevention

When it happens

Trigger: Currently declared as a package-level sentinel (pkg/project/stack.go:121) for the dev-on-protected-stage path; in this codebase no call site returns it — `sst dev` on a protected stage is rejected upstream/CLI-side before reaching Run. It fires conceptually when the dev command targets a stage with app.protect enabled.

Common situations: A developer points `sst dev --stage prod` at the production stage to 'debug in prod' and is blocked; local dev config accidentally inherits a protected stage name via SST_STAGE environment variable.

Related errors


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