pulumi/pulumi · error

creating environment: %w

Error message

creating environment: %w

What it means

After confirming the ESC environment does not exist, ensureProviderEnv calls env.esc.client.CreateEnvironment to create it. Any error returned by that API call is wrapped as `creating environment: %w` and aborts the provider login flow, since the provider node cannot be merged into a nonexistent environment.

Source

Thrown at pkg/cmd/esc/cli/env_provider_common.go:65

	return strings.Join(parts, ".")
}

// ensureProviderEnv creates the target environment if --create was passed and
// the environment does not already exist. It is a no-op when create is false
// or when the environment exists.
func ensureProviderEnv(ctx context.Context, env *envCommand, ref environmentRef, create bool) error {
	if !create {
		return nil
	}
	exists, err := env.esc.client.EnvironmentExists(ctx, ref.orgName, ref.projectName, ref.envName)
	if err != nil && !client.IsNotFound(err) {
		return fmt.Errorf("checking environment existence: %w", err)
	}
	if exists {
		return nil
	}
	if err := env.esc.client.CreateEnvironment(ctx, ref.orgName, ref.projectName, ref.envName); err != nil {
		return fmt.Errorf("creating environment: %w", err)
	}
	fmt.Fprintf(env.esc.stdout, "Environment created: %v\n", ref.String())
	return nil
}

// mergeProviderIntoEnv merges providerNode into the YAML environment definition at
// values.<path>, replacing any existing node at that path, and sets each of envVars under
// values.environmentVariables (adding to, not replacing, any variables already there). It
// returns the new YAML document bytes and whether they differ from the definition.
//
// changed compares the merge result against the definition re-marshaled through the same
// encoder, not against the raw input bytes, so that formatting normalization alone does not
// count as a change: a merge that sets already-present values reports changed == false.
func mergeProviderIntoEnv(
	envYAML []byte, path resource.PropertyPath, providerNode *yaml.Node, envVars []envVar,
) (newYAML []byte, changed bool, err error) {
	if len(path) == 0 {
		return nil, false, errors.New("path must contain at least one element")

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Re-run the command — if the environment now exists, drop --create or let the flow detect it
  2. Verify your Pulumi token has permission to create environments in the target org/project
  3. Check the environment name for invalid characters or length limits
  4. Inspect the wrapped inner error for the specific API failure (403, 409, etc.)

Example fix

// before
pulumi esc env provider azure login --create --project p --env prod-shared ...   // 409: already created by CI
// after
pulumi esc env provider azure login --project p --env prod-shared ...   // environment already exists; omit --create
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check existence so --create races are avoided
const exists = await escClient.environmentExists(org, project, envName)
const args = exists ? [] : ['--create']
runEscProviderAzureLogin([...args, tenant, sub, client])

Try / catch

try {
  runEscProviderAzureLogin(['--create', tenant, sub, client])
} catch (e) {
  if (/creating environment:/.test(e.message)) {
    if (/409|already exists/i.test(e.message)) {
      // lost a create race; proceed without --create
      return runEscProviderAzureLogin([tenant, sub, client])
    }
    console.error('Check permissions/naming for the target org/project:', e.message)
  } else throw e
}

Prevention

When it happens

Trigger: Running the provider login command with --create when the environment check passed (not found) but creation fails: permission denied for the org/project, an invalid environment name, or a concurrent process created the environment between the exists-check and the create (race).

Common situations: A teammate or CI job created the same environment moments earlier, the caller's token lacks the org's environments-write permission, or the environment name violates backend naming rules.

Related errors


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