{"record":{"id":"c0e46ef4c8268fcf","repo":"hashicorp/terraform","slug":"cowardly-refusing-to-delete-the-q-state","errorCode":null,"errorMessage":"cowardly refusing to delete the %q state","messagePattern":"cowardly refusing to delete the %q state","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/backend/remote-state/gcs/backend_state.go","lineNumber":69,"sourceCode":"\t\tif !strings.HasSuffix(name, stateFileSuffix) {\n\t\t\tcontinue\n\t\t}\n\t\tst := strings.TrimSuffix(name, stateFileSuffix)\n\n\t\tif st != backend.DefaultStateName {\n\t\t\tstates = append(states, st)\n\t\t}\n\t}\n\n\tsort.Strings(states[1:])\n\treturn states, diags\n}\n\n// DeleteWorkspace deletes the named workspaces. The \"default\" state cannot be deleted.\nfunc (b *Backend) DeleteWorkspace(name string, _ bool) tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\tif name == backend.DefaultStateName {\n\t\treturn diags.Append(fmt.Errorf(\"cowardly refusing to delete the %q state\", name))\n\t}\n\n\tc, err := b.client(name)\n\tif err != nil {\n\t\treturn diags.Append(err)\n\t}\n\n\treturn diags.Append(c.Delete())\n}\n\n// client returns a remoteClient for the named state.\nfunc (b *Backend) client(name string) (*remoteClient, error) {\n\tif name == \"\" {\n\t\treturn nil, fmt.Errorf(\"%q is not a valid state name\", name)\n\t}\n\n\treturn &remoteClient{\n\t\tstorageClient: b.storageClient,","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/gcs/backend_state.go#L51-L87","documentation":"DeleteWorkspace refuses to delete the workspace literally named 'default' (backend.DefaultStateName). The default workspace is special in Terraform and must always exist, so the GCS backend hard-blocks the operation regardless of the force flag. The %q is always 'default'.","triggerScenarios":"Calling 'terraform workspace delete default' or invoking DeleteWorkspace(\"default\", _) programmatically against the GCS backend.","commonSituations":"Scripted cleanup that loops over all workspaces and tries to delete each including default; CI teardown that nukes everything; misunderstanding that default is reserved.","solutions":["Skip 'default' in any bulk-delete loop: filter the name out before calling DeleteWorkspace.","If you want to reset default state, delete its contents (terraform state push of an empty state) rather than the workspace itself.","Update scripts: for w in $(terraform workspace list | grep -v default); do terraform workspace delete \"$w\"; done."],"exampleFix":"// before\nfor name := range workspaces {\n    backend.DeleteWorkspace(name, true)  // fails on \"default\"\n}\n\n// after\nfor name := range workspaces {\n    if name == backend.DefaultStateName { continue }\n    backend.DeleteWorkspace(name, true)\n}","handlingStrategy":"validation","validationCode":"for _, name := range workspaces {\n    if name == backend.DefaultStateName { continue }  // never delete default\n    _ = backend.DeleteWorkspace(name, true)\n}","typeGuard":"func isDefaultState(name string) bool { return name == \"default\" }","tryCatchPattern":null,"preventionTips":["Always exclude 'default' from bulk-delete loops.","Document the reservation in team runbooks.","Use terraform workspace list output filtering rather than ad-hoc iteration."],"tags":["gcs","gcp","workspaces","default-state","config-validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}