{"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/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/pg/backend_state.go#L30-L66","documentation":"Thrown by Backend.DeleteWorkspace in the PostgreSQL state backend when the requested workspace name equals backend.DefaultStateName (\"default\") or the empty string. The default workspace holds the canonical state and must never be removed; deleting it would orphan all resources in the DB. This is a hard guard at the top of DeleteWorkspace before any SQL runs.","triggerScenarios":"DeleteWorkspace(name, _) is called with name == \"default\" or name == \"\". Triggered by `tofu workspace delete default`, `tofa workspace select` paths that try to delete the active default, or tooling that iterates workspaces and tries to delete all of them including default.","commonSituations":"Cleanup script that deletes every workspace; CI teardown that calls `tofu workspace delete` on the default; misunderstanding that the default workspace is immutable-by-deletion.","solutions":["Skip the default workspace in any cleanup loop: `if [ \"$ws\" != \"default\" ]; then tofu workspace delete \"$ws\"; fi`.","Do not call DeleteWorkspace on \"\" - guard against empty names from upstream config.","To 'reset' default state, run `tofu destroy` against it instead of deleting the workspace."],"exampleFix":"# before\ntofu workspace delete default\n# after - reset state instead of deleting the workspace\ntofu workspace select default\ntofu destroy","handlingStrategy":"validation","validationCode":"func deleteWorkspace(name string) error {\n    if name == backend.DefaultStateName || name == \"\" {\n        return fmt.Errorf(\"refusing to delete protected workspace %q; use `tofu destroy` to clear default state\", name)\n    }\n    // ... proceed\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Skip 'default' in every workspace-cleanup loop.","Treat the default workspace as immutable-by-deletion in tooling.","Use `tofu destroy` to clear default state instead of workspace deletion."],"tags":["postgres","workspace","default-state","guard"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}