{"record":{"id":"be3599803d8d81d2","repo":"hashicorp/terraform","slug":"can-t-delete-default-state-be3599","errorCode":null,"errorMessage":"can't delete default state","messagePattern":"can't delete default state","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/pg/backend_state.go","lineNumber":48,"sourceCode":"\tfor rows.Next() {\n\t\tvar name string\n\t\tif err := rows.Scan(&name); err != nil {\n\t\t\treturn nil, diags.Append(err)\n\t\t}\n\t\tresult = append(result, name)\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, diags.Append(err)\n\t}\n\n\treturn result, diags\n}\n\nfunc (b *Backend) DeleteWorkspace(name string, _ bool) tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\n\tif name == backend.DefaultStateName || name == \"\" {\n\t\treturn diags.Append(fmt.Errorf(\"can't delete default state\"))\n\t}\n\n\tquery := `DELETE FROM %s.%s WHERE name = $1`\n\t_, err := b.db.Exec(fmt.Sprintf(query, b.schemaName, statesTableName), name)\n\tif err != nil {\n\t\treturn diags.Append(err)\n\t}\n\n\treturn diags\n}\n\nfunc (b *Backend) StateMgr(name string) (statemgr.Full, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\n\t// Build the state client\n\tvar stateMgr statemgr.Full = &remote.State{\n\t\tClient: &RemoteClient{\n\t\t\tClient:     b.db,","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/pg/backend_state.go#L30-L66","documentation":"Returned by Backend.DeleteWorkspace (pg/backend_state.go:48) when the requested workspace name equals backend.DefaultStateName (\"default\") or is empty. The default workspace is mandatory in the Postgres backend and can never be deleted; this is a deliberate guard, not a runtime fault.","triggerScenarios":"Calling `terraform workspace delete default`, `terraform workspace delete \"\"`, or invoking Backend.DeleteWorkspace(\"default\") programmatically. Bulk-automation that iterates Workspaces() and deletes each name without skipping \"default\" hits this.","commonSituations":"A cleanup script enumerates all workspaces and deletes them, forgetting to skip default; a migration/playbook passes an empty name by mistake; tooling that treats the workspace list as fully deletable.","solutions":["Skip the \"default\" entry in any workspace-deletion loop.","If you meant to reset default's state, use `terraform state` subcommands or `terraform apply -destroy` instead of deleting the workspace.","Validate the name is non-empty and not \"default\" before calling DeleteWorkspace."],"exampleFix":"// before: deletes everything returned by Workspaces()\n// for _, ws := range workspaces { backend.DeleteWorkspace(ws, false) }\n\n// after: skip the protected default\n// for _, ws := range workspaces {\n//   if ws == \"default\" || ws == \"\" { continue }\n//   backend.DeleteWorkspace(ws, false)\n// }","handlingStrategy":"validation","validationCode":"// Never attempt to delete the default workspace\n// if name == \"\" || name == backend.DefaultStateName {\n//   return fmt.Errorf(\"refusing to delete protected workspace %q\", name)\n// }\n// backend.DeleteWorkspace(name, false)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always filter out \"default\" when iterating Workspaces() for deletion.","Treat the workspace list as partially-protected in automation.","Validate user-supplied workspace names before calling DeleteWorkspace."],"tags":["postgres","workspace","validation","guard"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}