From 407c5b4699dc0db78ae9aae6dcf84f1e35a2e49b Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Mon, 6 Jul 2026 10:30:25 -0400 Subject: [PATCH] Create FwLite data directories at FwLiteWeb startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FwLiteWeb never created its project or auth-cache directories, unlike the MAUI host (FwLiteMauiKernel). That was harmless while the paths defaulted to the working directory, but a host can point LcmCrdt:ProjectPath and Auth:CacheFileName at a per-user location that doesn't exist yet. When it does, a missing directory makes project listing (Directory.EnumerateFiles), project creation (SQLite open), and MSAL cache init all throw. Create both directories up front in SetupAppServer so every host — not just the one passing the path — is covered. Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/FwLite/FwLiteWeb/FwLiteWebServer.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/backend/FwLite/FwLiteWeb/FwLiteWebServer.cs b/backend/FwLite/FwLiteWeb/FwLiteWebServer.cs index 29978b9dfa..7e329a25f5 100644 --- a/backend/FwLite/FwLiteWeb/FwLiteWebServer.cs +++ b/backend/FwLite/FwLiteWeb/FwLiteWebServer.cs @@ -74,6 +74,7 @@ public static WebApplication SetupAppServer(WebApplicationOptions options, Actio configure?.Invoke(builder); var app = builder.Build(); app.Logger.LogInformation("FwLite FwLiteWeb startup"); + EnsureDataDirectoriesExist(app); // Configure the HTTP request pipeline. app.UseSwagger(); app.UseSwaggerUI(o => @@ -134,4 +135,23 @@ public static WebApplication SetupAppServer(WebApplicationOptions options, Actio .AddAdditionalAssemblies(typeof(FwLiteShared._Imports).Assembly); return app; } + + /// + /// Creates the project and auth-cache directories up front, the way the MAUI host already does + /// (see FwLiteMauiKernel). FwLiteWeb never did, which was harmless while the paths defaulted + /// to the working directory (always present), but a host can point LcmCrdt:ProjectPath / + /// Auth:CacheFileName at a per-user location that doesn't exist yet — the Platform.Bible + /// extension does, and it can't create the directory itself. Without this, a missing directory makes + /// project listing (), project creation + /// (SQLite can't open a file under a missing directory), and MSAL cache init all fail. + /// + private static void EnsureDataDirectoriesExist(WebApplication app) + { + var projectPath = app.Services.GetRequiredService>().Value.ProjectPath; + Directory.CreateDirectory(projectPath); + + var cacheFileName = app.Services.GetRequiredService>().Value.CacheFileName; + var cacheDir = Path.GetDirectoryName(cacheFileName); + if (!string.IsNullOrEmpty(cacheDir)) Directory.CreateDirectory(cacheDir); + } }