{"record":{"id":"9e3863b8ee165943","repo":"felixse/FluentTerminal","slug":"failed-to-save-the-file","errorCode":null,"errorMessage":"Failed to save the file.","messagePattern":"Failed to save the file\\.","errorType":"exception","errorClass":"SaveTextFileException","httpStatus":null,"severity":"error","filePath":"FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs","lineNumber":81,"sourceCode":"            var response = await GetResponseAsync<StringValueResponse>(new GetUserNameRequest()).ConfigureAwait(false);\n\n            if (response.Success)\n            {\n                _userName = response.Value;\n            }\n\n            return _userName;\n        }\n\n        public async Task SaveTextFileAsync(string path, string content)\n        {\n            var response =\n                await GetResponseAsync<CommonResponse>(new SaveTextFileRequest {Path = path, Content = content})\n                    .ConfigureAwait(false);\n\n            if (!response.Success)\n            {\n                throw new SaveTextFileException(string.IsNullOrEmpty(response.Error)\n                    ? \"Failed to save the file.\"\n                    : response.Error);\n            }\n        }\n\n        public async Task<string> ReadTextFileAsync(string path)\n        {\n            var response = await GetResponseAsync<StringValueResponse>(new ReadTextFileRequest { Path = path }).ConfigureAwait(false);\n\n            if (!response.Success)\n            {\n                throw new ReadTextFileException(string.IsNullOrWhiteSpace(response.Error) ? \"Failed to read the file.\" : response.Error);\n            }\n\n            return response.Value;\n        }\n\n        public async Task<string> GetSshConfigDirAsync()","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/felixse/FluentTerminal/blob/ba83ec485eea8d8ee65825711731300bee2e76ed/FluentTerminal.App.Services/Implementation/TrayProcessCommunicationService.cs#L63-L99","documentation":"Thrown by TrayProcessCommunicationService.SaveTextFileAsync when the system-tray (full-trust) side process returns a CommonResponse with Success == false and no Error string. The UWP app cannot write arbitrary files directly, so it delegates to the Win32 tray process via an AppService ValueSet; on failure with a blank error it substitutes the generic 'Failed to save the file.' message.","triggerScenarios":"SaveTextFileRequest is sent over the AppService connection; the tray handler catches an IOException/UnauthorizedAccessException and returns Success=false. If the handler does not populate response.Error, the default message is used.","commonSituations":"Target path is read-only or denied by ACL; path points to a directory or invalid drive; disk full; tray process running with insufficient privileges for the chosen location; file locked by another process.","solutions":["Verify the target path is writable by the user and is not a directory, read-only file, or locked file.","Check the tray-side SaveTextFile handler to ensure it sets response.Error from the caught exception so the real cause is surfaced.","Run the app/tray with appropriate privileges if writing to a protected location.","Confirm the tray process is alive and the AppService connection is open (a dead tray yields no usable response)."],"exampleFix":"// before\nthrow new SaveTextFileException(string.IsNullOrEmpty(response.Error) ? \"Failed to save the file.\" : response.Error);\n\n// after (tray side) - always populate Error\n// catch (Exception ex) { return new CommonResponse { Success = false, Error = ex.Message }; }","handlingStrategy":"try-catch","validationCode":"// Validate path writability before delegating to the tray.\nif (string.IsNullOrWhiteSpace(path)) throw new ArgumentException(\"path required\");\nvar dir = System.IO.Path.GetDirectoryName(path);\nif (!System.IO.Directory.Exists(dir)) throw new System.IO.DirectoryNotFoundException(dir);","typeGuard":null,"tryCatchPattern":"try { await tray.SaveTextFileAsync(path, content); }\ncatch (SaveTextFileException ex) { logger.Warn(ex, \"save failed\"); notifyUser(ex.Message); }","preventionTips":["Pre-check the target directory exists and is writable before saving.","Ensure the tray-side handler always populates response.Error so the real cause surfaces.","Confirm the tray process is running before issuing file requests.","Avoid saving to system-protected paths without elevation."],"tags":["file-io","tray-ipc","appservice","permissions","uwp"],"backgroundTag":null,"analyzedSha":"ba83ec485eea8d8ee65825711731300bee2e76ed","analyzedAt":"2026-08-13T21:23:15.467Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}