{"record":{"id":"85e15248598d680f","repo":"hashicorp/terraform","slug":"error-deleting-workspace-s-w","errorCode":null,"errorMessage":"error deleting workspace %s: %w","messagePattern":"error deleting workspace (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/local/backend.go","lineNumber":254,"sourceCode":"\tvar diags tfdiags.Diagnostics\n\n\t// If we have a backend handling state, defer to that.\n\tif b.Backend != nil {\n\t\treturn b.Backend.DeleteWorkspace(name, force)\n\t}\n\n\tif name == \"\" {\n\t\treturn diags.Append(errors.New(\"empty state name\"))\n\t}\n\n\tif name == backend.DefaultStateName {\n\t\treturn diags.Append(errors.New(\"cannot delete default state\"))\n\t}\n\n\tdelete(b.states, name)\n\terr := os.RemoveAll(filepath.Join(b.stateWorkspaceDir(), name))\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error deleting workspace %s: %w\", name, err))\n\t}\n\n\treturn diags\n}\n\nfunc (b *Local) StateMgr(name string) (statemgr.Full, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\n\t// If we have a backend handling state, delegate to that.\n\tif b.Backend != nil {\n\t\treturn b.Backend.StateMgr(name)\n\t}\n\n\tif s, ok := b.states[name]; ok {\n\t\treturn s, diags\n\t}\n\n\tif err := b.createState(name); err != nil {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/local/backend.go#L236-L272","documentation":"Thrown by Local.DeleteWorkspace in the local backend when os.RemoveAll fails on the on-disk workspace state directory (filepath.Join(stateWorkspaceDir(), name)). The underlying OS error is wrapped with %w so callers can inspect it. DeleteWorkspace has already validated that name is non-empty and not the default workspace before reaching this point.","triggerScenarios":"Calling terraform workspace delete <name> (or backend.DeleteWorkspace programmatically) against the local backend, where RemoveAll returns a non-nil error: permission denied, not a directory, ENOENT after a race, read-only filesystem, or a file held open by another process (common on Windows).","commonSituations":"State directory chmod'd to read-only, antivirus or backup software locking the file on Windows, the workspace dir was already removed out-of-band, NFS/SMB share permission mismatch, or running as a different user than the one that created the state dir.","solutions":["Check the wrapped OS error first: `errors.Is(err, os.ErrPermission)` etc. to know whether it is permissions, missing path, or something else.","Fix filesystem permissions on the state workspace directory so the terraform process can write and remove files under it.","Close any process holding the file open (editors, antivirus, sync clients) and retry.","If the directory was already removed externally, the workspace is effectively gone; clean up any cached in-memory entry and re-list workspaces."],"exampleFix":"// before: assumes RemoveAll always succeeds\n_ = os.RemoveAll(filepath.Join(b.stateWorkspaceDir(), name))\n// after: surface + classify the error\nif err := os.RemoveAll(filepath.Join(b.stateWorkspaceDir(), name)); err != nil {\n    return diags.Append(fmt.Errorf(\"error deleting workspace %s: %w\", name, err))\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check the workspace dir is removable before calling DeleteWorkspace.\nfunc canRemoveWorkspaceDir(base, name string) error {\n    p := filepath.Join(base, name)\n    info, err := os.Stat(p)\n    if err != nil && !os.IsNotExist(err) { return err }\n    if err == nil && !info.IsDir() { return fmt.Errorf(\"%s is not a directory\", p) }\n    // attempt a no-op write to verify writability of the parent\n    return os.WriteFile(filepath.Join(base, \".rmprobe\"), []byte{}, 0o644)\n}","typeGuard":"null","tryCatchPattern":"if diags := b.DeleteWorkspace(name, force); diags.HasErrors() {\n    err := diags.Err()\n    if errors.Is(err, os.ErrPermission) {\n        // guide the user to fix perms\n    }\n    return err\n}","preventionTips":["Run terraform as a user that owns the state workspace directory.","On Windows, close editors/AV/sync clients that may hold state files open before deleting a workspace.","Do not chmod the state dir read-only; the local backend needs write access for create and delete."],"tags":["local-backend","workspace","filesystem","io"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}