{"record":{"id":"e9c898fc7f7c7cc3","repo":"d2phap/ImageGlass","slug":"ige-could-not-move-the-file-to-trash-filepath","errorCode":null,"errorMessage":"IGE: Could not move the file to trash: {filePath}","messagePattern":"IGE: Could not move the file to trash: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"source/ImageGlass.Linux/Common/ServiceProviders/LinuxShellProvider.cs","lineNumber":75,"sourceCode":"        // Linux does not support foreground shell integration\n        return false;\n    }\n\n\n    /// <summary>\n    /// <inheritdoc/>\n    /// </summary>\n    public void DeleteFile(string filePath, bool moveToRecycleBin = true)\n    {\n        if (moveToRecycleBin)\n        {\n            // Move to the user's real trash via the FreeDesktop spec. We don't use\n            // the Trash portal (broken on some desktops) or 'gio trash' (targets\n            // the sandbox trash inside Flatpak). Throw on failure so the caller\n            // surfaces an error instead of silently \"losing\" the file.\n            if (!FreeDesktopTrash.Trash(filePath))\n            {\n                throw new IOException($\"IGE: Could not move the file to trash: {filePath}\");\n            }\n        }\n        else\n        {\n            File.Delete(filePath);\n        }\n    }\n\n\n    /// <summary>\n    /// <inheritdoc/>\n    /// </summary>\n    public object? GetForegroundWindowView()\n    {\n        // Linux does not have a foreground shell object\n        return null;\n    }\n","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/d2phap/ImageGlass/blob/4a3c4feceffc5a8bb5e56ba836509634aaae47a9/source/ImageGlass.Linux/Common/ServiceProviders/LinuxShellProvider.cs#L57-L93","documentation":"Thrown by LinuxShellProvider.DeleteFile when moveToRecycleBin is true and FreeDesktopTrash.Trash returns false. On Linux the host implements the FreeDesktop trash spec directly (home trash at $HOME/.local/share/Trash) rather than relying on a portal or gio. A false return means the file could not be moved/copied into the home trash — for any of the documented failure modes in FreeDesktopTrash.cs.","triggerScenarios":"Produced at LinuxShellProvider.cs:75 when FreeDesktopTrash.Trash(filePath) returns false. Trash returns false when: the file does not exist, $HOME is unset/empty, the trash info file cannot be created after 10000 name collisions, or the final File.Move/File.Copy/File.Delete fails (permissions, read-only filesystem, cross-device copy failure).","commonSituations":"File already deleted by the time the call runs (race with file watcher); $HOME unset in a container/sandbox environment; file on a read-only mount; insufficient permissions on the source file or on ~/.local/share/Trash; Flatpak sandbox denies access to the home trash dir; path is on a filesystem that does not support the move and the copy-fallback also failed (out of space).","solutions":["Verify the file still exists at the moment of the call and that $HOME is set in the environment.","Check permissions on the source file and on ~/.local/share/Trash (must be writable by the user); inside Flatpak, ensure the home filesystem is granted.","If the file is on a different filesystem and the copy+delete fallback ran out of space, free space or move within the same filesystem.","Fall back to a permanent delete (DeleteFile with moveToRecycleBin=false) only if the user accepts data loss; otherwise surface the IO error."],"exampleFix":"// before\nif (!FreeDesktopTrash.Trash(filePath))\n    throw new IOException($\"IGE: Could not move the file to trash: {filePath}\");\n\n// after — capture the specific reason Trash returned false so the user can act\nvar reason = FreeDesktopTrash.Trash(filePath, out var trashError);\nif (!reason)\n    throw new IOException($\"IGE: Could not move the file to trash: {filePath} ({trashError})\");","handlingStrategy":"validation","validationCode":"// Before trashing, confirm the file exists and HOME is usable on Linux.\nif (!File.Exists(filePath) && !Directory.Exists(filePath)) throw new FileNotFoundException(filePath);\nif (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(\"HOME\"))) throw new InvalidOperationException(\"HOME unset\");\nvar trashRoot = Path.Combine(Environment.GetEnvironmentVariable(\"HOME\")!, \".local\", \"share\", \"Trash\");\nDirectory.CreateDirectory(Path.Combine(trashRoot, \"files\"));\nDirectory.CreateDirectory(Path.Combine(trashRoot, \"info\"));","typeGuard":"static bool CanTrash(string filePath) =>\n    (File.Exists(filePath) || Directory.Exists(filePath))\n    && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(\"HOME\"));","tryCatchPattern":"try { shellProvider.DeleteFile(filePath, moveToRecycleBin: true); }\ncatch (IOException ex) when (ex.Message.Contains(\"Could not move the file to trash\"))\n{ _log.Error($\"Trash failed for {filePath}: {ex.Message}\"); /* surface to user; do not auto-delete permanently */ }","preventionTips":["Confirm the file still exists at call time (race with file watchers is the most common cause).","Ensure $HOME is set and ~/.local/share/Trash is writable in the runtime (sandbox/Flatpak must grant it).","On cross-filesystem sources, ensure space for the copy+delete fallback.","Inside Flatpak, verify the home trash dir is reachable, not the sandbox-private one.","Never fall back to permanent delete automatically — surface the error and let the user decide."],"tags":["linux","filesystem","trash","io","platform"],"backgroundTag":null,"analyzedSha":"4a3c4feceffc5a8bb5e56ba836509634aaae47a9","analyzedAt":"2026-08-13T16:58:15.523Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}