pulumi/pulumi · error

pre-step event returned an error: %w

Error message

pre-step event returned an error: %w

What it means

Before executing a resource step, the engine emits a pre-step event to subscribers via events.OnResourceStepPre. If that handler returns an error, the step is not executed and the engine wraps the failure as 'pre-step event returned an error'. Like other event errors, it reflects a problem in an event consumer, not in the resource operation itself.

Source

Thrown at pkg/resource/deploy/step_executor.go:489

// verbatim to the post-step event.
//

// executeStep executes a single step, returning true if the step execution was successful and
// false if it was not.
func (se *stepExecutor) executeStep(workerID int, step Step) error {
	var payload any
	events := se.deployment.events

	// DiffSteps are special, we just use them for step worker parallelism but they shouldn't be passed to the rest of
	// the system.
	_, isDiff := step.(*DiffStep)

	if events != nil && !isDiff {
		var err error
		payload, err = events.OnResourceStepPre(step)
		if err != nil {
			se.log(workerID, "step %v on %v failed pre-resource step: %v", step.Op(), step.URN(), err)
			return fmt.Errorf("pre-step event returned an error: %w", err)
		}
	}

	return se.continueExecuteStep(payload, workerID, step)
}

func (se *stepExecutor) continueExecuteStep(payload any, workerID int, step Step) error {
	events := se.deployment.events

	se.log(workerID, "applying step %v on %v (preview %v)", step.Op(), step.URN(), se.deployment.opts.DryRun)
	status, stepComplete, err := step.Apply()

	// DiffSteps are special, we just use them for step worker parallelism but they shouldn't be passed to the rest of
	// the system.
	if _, isDiff := step.(*DiffStep); isDiff {
		return nil
	}

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Look at the logged line 'failed pre-resource step: %v' for the underlying handler error.
  2. Fix or remove the failing event subscriber (policy pack, automation consumer) before retrying.
  3. Check backend connectivity (PULUMI_ACCESS_TOKEN, self-hosted endpoint) if events publish to Pulumi Cloud.
  4. Retry the deployment once the consumer is fixed; the affected resource step never ran, so re-run is required.

Example fix

// before: automation API throws inside onEvent and aborts the deploy
await stack.up({ onEvent: ev => { if (ev.someField) throw new Error('bad'); } });
// after: log instead of throwing inside the event handler
await stack.up({ onEvent: ev => { if (ev.someField) console.error('bad event', ev); } });
Defensive patterns

Strategy: try-catch

Validate before calling

// smoke-test policy packs before wiring them into deploys
// pulumi policy rm <org>/<name> && pulumi policy publish <dir> && pulumi policy enable <org>/<name>

Try / catch

try {
  await stack.up({ onEvent: handle });
} catch (e) {
  if (/pre-step event returned an error/.test(String(e))) {
    console.error('A pre-step event handler (policy/backend/automation) failed; inspect 'failed pre-resource step' log line');
  }
  throw e;
}

Prevention

When it happens

Trigger: An event subscriber's OnResourceStepPre fails — e.g. the display/backend event channel is broken, a policy/preevent callback errors, or the Automation API consumer throws while handling the step-pre event.

Common situations: Pulumi Cloud event publishing outage; policy pack or crossguard callback crash; automation program crashing mid-deploy while the engine is still running; serializing an unserializable payload in a custom event consumer.

Related errors


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