{"record":{"id":"b73f8021c59fe9d6","repo":"pulumi/pulumi","slug":"creating-environment-w-b73f80","errorCode":null,"errorMessage":"creating environment: %w","messagePattern":"creating environment: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/esc/cli/env_provider_common.go","lineNumber":65,"sourceCode":"\treturn strings.Join(parts, \".\")\n}\n\n// ensureProviderEnv creates the target environment if --create was passed and\n// the environment does not already exist. It is a no-op when create is false\n// or when the environment exists.\nfunc ensureProviderEnv(ctx context.Context, env *envCommand, ref environmentRef, create bool) error {\n\tif !create {\n\t\treturn nil\n\t}\n\texists, err := env.esc.client.EnvironmentExists(ctx, ref.orgName, ref.projectName, ref.envName)\n\tif err != nil && !client.IsNotFound(err) {\n\t\treturn fmt.Errorf(\"checking environment existence: %w\", err)\n\t}\n\tif exists {\n\t\treturn nil\n\t}\n\tif err := env.esc.client.CreateEnvironment(ctx, ref.orgName, ref.projectName, ref.envName); err != nil {\n\t\treturn fmt.Errorf(\"creating environment: %w\", err)\n\t}\n\tfmt.Fprintf(env.esc.stdout, \"Environment created: %v\\n\", ref.String())\n\treturn nil\n}\n\n// mergeProviderIntoEnv merges providerNode into the YAML environment definition at\n// values.<path>, replacing any existing node at that path, and sets each of envVars under\n// values.environmentVariables (adding to, not replacing, any variables already there). It\n// returns the new YAML document bytes and whether they differ from the definition.\n//\n// changed compares the merge result against the definition re-marshaled through the same\n// encoder, not against the raw input bytes, so that formatting normalization alone does not\n// count as a change: a merge that sets already-present values reports changed == false.\nfunc mergeProviderIntoEnv(\n\tenvYAML []byte, path resource.PropertyPath, providerNode *yaml.Node, envVars []envVar,\n) (newYAML []byte, changed bool, err error) {\n\tif len(path) == 0 {\n\t\treturn nil, false, errors.New(\"path must contain at least one element\")","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/cmd/esc/cli/env_provider_common.go#L47-L83","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Re-run the command — if the environment now exists, drop --create or let the flow detect it","Verify your Pulumi token has permission to create environments in the target org/project","Check the environment name for invalid characters or length limits","Inspect the wrapped inner error for the specific API failure (403, 409, etc.)"],"exampleFix":"// before\npulumi esc env provider azure login --create --project p --env prod-shared ...   // 409: already created by CI\n// after\npulumi esc env provider azure login --project p --env prod-shared ...   // environment already exists; omit --create","handlingStrategy":"try-catch","validationCode":"// pre-check existence so --create races are avoided\nconst exists = await escClient.environmentExists(org, project, envName)\nconst args = exists ? [] : ['--create']\nrunEscProviderAzureLogin([...args, tenant, sub, client])","typeGuard":null,"tryCatchPattern":"try {\n  runEscProviderAzureLogin(['--create', tenant, sub, client])\n} catch (e) {\n  if (/creating environment:/.test(e.message)) {\n    if (/409|already exists/i.test(e.message)) {\n      // lost a create race; proceed without --create\n      return runEscProviderAzureLogin([tenant, sub, client])\n    }\n    console.error('Check permissions/naming for the target org/project:', e.message)\n  } else throw e\n}","preventionTips":["Ensure your token can create environments in the target org/project","Validate environment names against backend naming rules before invoking","Handle 409 (already exists) by dropping --create and re-running","Avoid concurrent CI jobs creating the same environment; use a single owner step"],"tags":["esc-api","permissions","race-condition"],"backgroundTag":"esc-environment-create-failed","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}