hashicorp/terraform · error

Invalid workspace name: The selected workspace described in

Error message

Invalid workspace name: The selected workspace described in %q has an invalid name. This suggests that the file contents were edited by something other than Terraform. To select a different, valid workspace name use commands `terraform workspace select` or `terraform workspace select -or-create`.

What it means

Returned from `WorkspaceOverridden` when the on-disk workspace file (`.terraform/terraform.tfstate.d/default` workspace marker, i.e. `local.DefaultWorkspaceFile` under `m.DataDir()`) contains a name that fails `validWorkspaceName`. The message explicitly warns that the file was likely hand-edited, because Terraform itself only ever writes valid names there.

Solutions

  1. Run `terraform workspace select <valid-name>` (or `-or-create`) — recovery commands set `bypassWorkspaceNameValidityCheck` and overwrite the file.
  2. If no valid workspace is intended, delete the marker file under `.terraform/` so Terraform falls back to `default`.
  3. Inspect the file content: `cat .terraform/<workspace-marker>` to see the invalid value.
  4. Remove the file from version control if it was accidentally committed.

Example fix

# before: file contains 'feat/x' (invalid)
# recover
terraform workspace select -or-create=true prod
# or remove the marker
rm -f .terraform/tfstack/default
# next terraform command will use the default workspace
Defensive patterns

Strategy: validation

Validate before calling

// Validate the workspace marker file contents before running.
data, _ := os.ReadFile(filepath.Join(dataDir, local.DefaultWorkspaceFile))
name := strings.TrimSpace(string(data))
if name != "" && !arguments.ValidWorkspaceName(name) {
    // delete it or run `terraform workspace select` to recover
}

Type guard

func validWs(s string) bool { return arguments.ValidWorkspaceName(s) }

Try / catch

// Use recovery commands (workspace select) which set bypassWorkspaceNameValidityCheck.
// They overwrite the marker with a valid name.

Prevention

When it happens

Trigger: `os.ReadFile(filepath.Join(m.DataDir(), local.DefaultWorkspaceFile))` succeeds, the trimmed content is non-empty (so not default), but `validWorkspaceName(current)` is false. The `bypassWorkspaceNameValidityCheck` flag is false (it is only enabled for recovery commands like `workspace select`).

Common situations: A user or script manually edited `.terraform/tfstack/default` / the workspace marker file; a sync tool corrupted the file; the file was checked into version control with an invalid value; partial filesystem corruption after a crash.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/cad80f457093a47d. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/meta.go:811

// whether the workspace is set by ENV or not.
func (m *Meta) WorkspaceOverridden() (string, bool, error) {
	if envVar := os.Getenv(WorkspaceNameEnvVar); envVar != "" {
		if !validWorkspaceName(envVar) {
			// Protect against invalid workspace names set via ENV.
			return "", true, errInvalidWorkspaceNameEnvVar
		}
		return envVar, true, nil
	}

	envData, err := os.ReadFile(filepath.Join(m.DataDir(), local.DefaultWorkspaceFile))
	current := string(bytes.TrimSpace(envData))
	if current == "" {
		current = backend.DefaultStateName
	}
	if !m.bypassWorkspaceNameValidityCheck && !validWorkspaceName(current) {
		// This check is active in every command that uses a backend.
		// It is selectively disabled in commands that are recommended for recovering from an invalid workspace.
		err := fmt.Errorf("Invalid workspace name: The selected workspace described in %q has an invalid name. This suggests that the file contents were edited by something other than Terraform. To select a different, valid workspace name use commands `terraform workspace select` or `terraform workspace select -or-create`.", filepath.Join(m.DataDir(), local.DefaultWorkspaceFile))
		return "", false, err
	}

	if err != nil && !os.IsNotExist(err) {
		// always return the default if we can't get a workspace name
		log.Printf("[ERROR] failed to read current workspace: %s", err)
	}

	return current, false, nil
}

// SetWorkspace saves the given name as the current workspace in the local
// filesystem.
func (m *Meta) SetWorkspace(name string) error {
	err := os.MkdirAll(m.DataDir(), 0755)
	if err != nil {
		return err
	}

View on GitHub (pinned to d32a084675)