{"record":{"id":"9692db18551c7569","repo":"charmbracelet/crush","slug":"failed-to-rename-file-w","errorCode":null,"errorMessage":"failed to rename file: %w","messagePattern":"failed to rename file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lsp/util/edit.go","lineNumber":231,"sourceCode":"\t\toldPath, err = change.RenameFile.OldURI.Path()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tnewPath, err = change.RenameFile.NewURI.Path()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif change.RenameFile.Options != nil {\n\t\t\tif !change.RenameFile.Options.Overwrite {\n\t\t\t\tif _, err := os.Stat(newPath); err == nil {\n\t\t\t\t\treturn fmt.Errorf(\"target file already exists and overwrite is not allowed: %s\", newPath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err := os.Rename(oldPath, newPath); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to rename file: %w\", err)\n\t\t}\n\t}\n\n\tif change.TextDocumentEdit != nil {\n\t\ttextEdits := make([]protocol.TextEdit, len(change.TextDocumentEdit.Edits))\n\t\tfor i, edit := range change.TextDocumentEdit.Edits {\n\t\t\tvar err error\n\t\t\ttextEdits[i], err = edit.AsTextEdit()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid edit type: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn applyTextEdits(change.TextDocumentEdit.TextDocument.URI, textEdits, encoding)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/lsp/util/edit.go#L213-L249","documentation":"applyDocumentChange wraps any failure from os.Rename(oldPath, newPath) when applying an LSP RenameFile change. os.Rename fails at the OS level (not because of policy like overwrite rules), so the wrapped error carries the syscall reason. The original error is preserved via %w.","triggerScenarios":"os.Rename fails: oldPath does not exist, paths span different mount points/filesystems (EXDEV), permission denied, or newPath's parent directory does not exist.","commonSituations":"Renaming into a directory that was deleted or never created; moving a file across filesystems (e.g. /tmp to a mounted volume); file locked/held by another process on Windows; running without write permission on the source or destination directory.","solutions":["Read the wrapped os error (os.IsNotExist, *fs.PathError) and verify both oldPath and newPath parent directory exist before calling ApplyWorkspaceEdit","Create the destination directory first (os.MkdirAll)","Ensure old and new paths are on the same filesystem, or fall back to copy+delete across devices","Check process permissions on both paths"],"exampleFix":"// before\nerr := ApplyWorkspaceEdit(edit, enc)\n// after\nif err := os.MkdirAll(filepath.Dir(newPath), 0o755); err != nil {\n    return err\n}\nif _, err := os.Stat(oldPath); err != nil {\n    return fmt.Errorf(\"source missing: %w\", err)\n}\nerr = ApplyWorkspaceEdit(edit, enc)","handlingStrategy":"validation","validationCode":"func canRename(oldPath, newPath string) error {\n    if _, err := os.Stat(oldPath); err != nil {\n        return fmt.Errorf(\"source missing: %w\", err)\n    }\n    if err := os.MkdirAll(filepath.Dir(newPath), 0o755); err != nil {\n        return err\n    }\n    if of, nf := filepath.Abs(oldPath), filepath.Abs(newPath); filepath.Dir(of) != filepath.Dir(nf) {\n        // warn: potential cross-device rename\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var pathErr *fs.PathError\nif err := ApplyWorkspaceEdit(edit, enc); err != nil {\n    if errors.As(err, &pathErr) {\n        log.Printf(\"rename failed at %s: %v\", pathErr.Path, pathErr.Err)\n    }\n}","preventionTips":["Ensure the destination directory exists before applying rename edits","Keep renames within one filesystem; implement copy+delete fallback for cross-device moves","Check write permissions on source and destination directories"],"tags":["lsp","filesystem","rename","oserror"],"backgroundTag":"rename-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}