{"record":{"id":"fde0f20b6c07ac58","repo":"wavetermdev/waveterm","slug":"failed-to-delete-file-w-fde0f2","errorCode":null,"errorMessage":"failed to delete file: %w","messagePattern":"failed to delete file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveappstore/waveappstore.go","lineNumber":336,"sourceCode":"}\n\nfunc DeleteAppFile(appId string, fileName string) error {\n\tif err := ValidateAppId(appId); err != nil {\n\t\treturn fmt.Errorf(\"invalid appId: %w\", err)\n\t}\n\n\tappDir, err := GetAppDir(appId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfilePath, err := validateAndResolveFilePath(appDir, fileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.Remove(filePath); err != nil {\n\t\treturn fmt.Errorf(\"failed to delete file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc ReplaceInAppFile(appId string, fileName string, edits []fileutil.EditSpec) error {\n\tif err := ValidateAppId(appId); err != nil {\n\t\treturn fmt.Errorf(\"invalid appId: %w\", err)\n\t}\n\n\tappDir, err := GetAppDir(appId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfilePath, err := validateAndResolveFilePath(appDir, fileName)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveappstore/waveappstore.go#L318-L354","documentation":"DeleteAppFile removes the resolved file with os.Remove and wraps any failure (waveappstore.go:335-337). Note that on POSIX os.Remove can delete directories too, but the common failure is the file not existing (fs.ErrNotExist) or lacking write permission on the containing directory.","triggerScenarios":"Calling DeleteAppFile (or DeleteAppFileCommand) for a fileName that does not exist in the app dir; deleting a file inside a directory the user cannot write; deleting a non-empty directory entry or a file on a read-only filesystem.","commonSituations":"Double-delete after a first successful delete (idempotency bug); deleting files generated by the build that were already cleaned up; permissions broken by running the app under a different user; ENOSPC-adjacent read-only remount after disk errors.","solutions":["Check errors.Is(err, fs.ErrNotExist) and treat as success if you want idempotent deletes.","If permission denied, fix write permission on the app directory (you need write on the dir, not the file).","Verify the app/file exists first with ListAllAppFiles or os.Stat.","If the filesystem is read-only, remount rw or free the disk and retry."],"exampleFix":"// before: non-idempotent delete\ncleanup := func() error { return waveappstore.DeleteAppFile(appId, \"tmp.out\") }\n\n// after: tolerate already-deleted files\nif err := waveappstore.DeleteAppFile(appId, \"tmp.out\"); err != nil && !errors.Is(err, fs.ErrNotExist) {\n    return err\n}","handlingStrategy":"try-catch","validationCode":"func filePresent(appId, fileName string) bool {\n    dir, err := waveappstore.GetAppDir(appId)\n    if err != nil { return false }\n    _, err = os.Stat(filepath.Join(dir, filepath.Clean(fileName)))\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"err := waveappstore.DeleteAppFile(appId, fileName)\nif err != nil && errors.Is(err, fs.ErrNotExist) {\n    return nil // already deleted — idempotent success\n}\nif err != nil {\n    return err\n}","preventionTips":["Make deletes idempotent by accepting fs.ErrNotExist.","You need write permission on the app directory, not the file itself.","Check existence first if you must report 'deleted' vs 'not found' differently.","Handle read-only-filesystem errors distinctly from not-found."],"tags":["filesystem","go","file-delete","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}