pulumi/pulumi · error · AutoError

failed to cancel update: %w

Error message

failed to cancel update: %w

What it means

This error is returned by Stack.Cancel when the underlying `pulumi cancel` command fails to terminate a running update. It is wrapped in an AutoError carrying the command's stdout, stderr, and exit code so callers can inspect the CLI failure. The %w preserves the original exec error for errors.Is/As checks.

Source

Thrown at sdk/go/auto/stack.go:1355

// Note that this operation is _very dangerous_, and may leave the stack in an inconsistent state
// if a resource operation was pending when the update was canceled.
func (s *Stack) Cancel(ctx context.Context) error {
	bo := s.cliBaseOptions()
	stack := s.Name()
	api, ok := s.cliAPI()
	if !ok {
		return errors.New("Stack.Cancel requires a *LocalWorkspace; the workspace does not expose a generated CLI API")
	}
	result, err := api.Cancel(ctx, nil, func(o *optcancel.Options) {
		o.Cwd = bo.Cwd
		o.AdditionalEnv = bo.AdditionalEnv
		o.Stdout = bo.Stdout
		o.Stderr = bo.Stderr
		o.Stdin = bo.Stdin
		o.Stack = stack
	})
	if err != nil {
		return newAutoError(fmt.Errorf("failed to cancel update: %w", err),
			result.Stdout, result.Stderr, result.ExitCode)
	}
	if cbErr := s.Workspace().PostCommandCallback(ctx, stack); cbErr != nil {
		return fmt.Errorf("command ran successfully, but error running PostCommandCallback: %w", cbErr)
	}
	return nil
}

// cliAPI returns the workspace's auto-generated CLI API. The second
// return is false when the workspace is not a *LocalWorkspace.
func (s *Stack) cliAPI() (*automation.API, bool) {
	lws, ok := s.workspace.(*LocalWorkspace)
	if !ok || lws == nil {
		return nil, false
	}
	return lws.cliAPI, lws.cliAPI != nil
}

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Inspect the AutoError's Stdout/Stderr/ExitCode fields to see the CLI's cancellation failure reason
  2. Verify the pulumi CLI is on PATH and its version is supported by the automation API
  3. Check the stack actually has a running update (`pulumi stack history`) before canceling
  4. Re-authenticate (pulumi login) if the backend rejected the request

Example fix

// before
if err := stack.Cancel(ctx); err != nil { log.Fatal(err) }
// after
var autoErr *auto.AutoError
if err := stack.Cancel(ctx); err != nil {
    if errors.As(err, &autoErr) {
        log.Printf("cancel failed: exit=%d stdout=%s stderr=%s", autoErr.ExitCode, autoErr.Stdout, autoErr.Stderr)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("pulumi"); err != nil { return fmt.Errorf("pulumi CLI not found: %w", err) }

Type guard

var ae *auto.AutoError
if errors.As(err, &ae) { /* inspect ae.Stdout, ae.Stderr, ae.ExitCode */ }

Try / catch

err := stack.Cancel(ctx)
var ae *auto.AutoError
if errors.As(err, &ae) {
    log.Printf("cancel failed exit=%d: %s", ae.ExitCode, ae.Stderr)
}
return err

Prevention

When it happens

Trigger: Calling stack.Cancel(ctx) when the workspace cannot locate the Stack, the Pulumi CLI binary is missing or mis-versioned, or the `pulumi stack cancel --yes` subprocess exits non-zero.

Common situations: Stale PULUMI_ACCESS_TOKEN, the stack was already canceled/completed, offline with Pulumi Cloud backend, or a broken PATH where the pulumi binary cannot be executed.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/b2d0cf76760cfff5. Report an issue: GitHub.