Skip to content

Fix --home-dir log path and missing app folder errors - #1766

Merged
mohnjiles merged 6 commits into
LykosAI:mainfrom
e-nord:fix-linux-home-dir-log-path
Oct 11, 2026
Merged

mohnjiles merged 6 commits into
LykosAI:mainfrom
e-nord:fix-linux-home-dir-log-path

Conversation

@e-nord

@e-nord e-nord commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Changes

  • Logs follow --home-dir. The log file target is built from Compat.AppDataHome, and the path is escaped with SimpleLayout.Escape so NLog treats it literally. A relative --home-dir is resolved to a full path.
  • Named folder paths. Compat.LogsDir and SettingsManager.PackagesDirectory replace the hand-built paths.
  • SettingsManager.EnsureAppDirectories() creates the app's well-known folders: AppDataHome, Logs, Packages, Workflows, Images, ExtensionPacks and the default Models folder.
    • It runs when the library is found, after LoadSettings. The three TryFindLibrary branches now share LoadLibrary().
    • It never creates a Models override or Images/Consolidated.
    • Failures are logged, not thrown.
    • The Workflows and Outputs pages call it instead of creating their own folders.
  • Missing folders and files show a notification. IOCommands.OpenFolderBrowserAsync and OpenFileBrowserAsync show a "Folder not found" or "File not found" warning, and they never create anything. The Settings → App Folders shortcuts call EnsureAppDirectories() before opening. CreateLogFolderZip handles a missing Logs folder.

Testing

  • New LogFileTargetTests and SettingsManagerDirectoriesTests.
  • Manual check on Windows with --home-dir set to a folder named ${shortdate}: logs, the Packages and Logs shortcuts, and recreating deleted folders.
  • Unit suite: 629 passed. The one failure (TestGetInstalledExtensionsLiteAsync) also fails on main.

Note: other hardcoded paths that could drift (not changed here)

  • LibraryDir/Packages/<name> is built by hand in PackageInstallDetailViewModel, both one-click install view models and BaseGitPackage.DownloadLocation. These could use PackagesDirectory.
  • Library-relative LibraryPath values use a literal "Packages" in about 7 places.
  • PackageInstallDetailViewModel and IndexUnknownPackages compare LibraryPath as plain strings using the current OS separator. They could miss matches for a library moved between Windows and Unix. This hasn't been reproduced.
  • GlobalConfig.ModelsDir is set before settings load, so it ignores a ModelDirectoryOverride.

🤖 Generated with Claude Code

@mohnjiles mohnjiles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two path-handling edge cases on the current head. The NLog layout case was reproduced on Windows with the pinned NLog 5.3.2; the Unix backslash case is based on static path analysis.

Comment thread StabilityMatrix.Avalonia/App.axaml.cs Outdated
Comment thread StabilityMatrix.Avalonia/App.axaml.cs Outdated
@e-nord e-nord changed the title Fix log folder location when using --home-dir Fix --home-dir log path and missing app folder errors Oct 8, 2026

@ionite34 ionite34 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice PR, thanks! The --home-dir log fix with escaping plus tests is exactly right, and folding the three TryFindLibrary branches into LoadLibrary() is a good cleanup 🐺

One design ask before we approve: could LoadLibrary() skip calling EnsureAppDirectories(), so TryFindLibrary only finds and loads the library?

The fixes don't depend on that startup call. The places that open folders already handle it themselves:

  • OpenDirectoryShortcut calls EnsureAppDirectories() right before opening.
  • Workflows and Outputs call it on load.
  • IOCommands shows the not-found warning.

Those use-site calls also cover a folder deleted after startup, which the startup call can't. Without it there's no side effect hidden inside a method named Try/Find. Logs, AppData and Models already get created elsewhere: NLog, SetLibraryPath, SetupSharedModelFolders.

SettingsManagerDirectoriesTests would then call EnsureAppDirectories() directly instead of going through TryFindLibrary.

Happy to push that change on top if you'd prefer, just say so!

e-nord and others added 6 commits October 10, 2026 17:38
The NLog file target was hardcoded to %AppData%/StabilityMatrix/Logs, while
the Settings "Logs" shortcut and the exception dialog's log zip read from
Compat.AppDataHome/Logs. With --home-dir set, those diverged and the log
folder never existed, throwing DirectoryNotFoundException.

Also resolve a relative --home-dir to a full path so folder-browser calls
and file:// URIs don't receive relative paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FileName and ArchiveFileName are parsed as NLog layouts, so a home
directory containing "${...}" (e.g. "${shortdate}") was rendered instead
of used literally, sending logs to a different folder than Settings and
the log zip read from. Escape the path with SimpleLayout.Escape.

Drop the backslash-to-slash rewrite: NLog treats backslashes literally
outside "${...}", and on Unix a backslash is a valid filename character.

Move file target setup into LogFileTarget.Create so it can be tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the hand-built AppDataHome/Logs and LibraryDir/Packages paths
with named properties, so each well-known folder is defined in one place.
No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Folders like Packages were only created on first use (e.g. the first
package install), so Settings > App Folders > Packages crashed on a fresh
library. Add SettingsManager.EnsureAppDirectories() as the one place that
creates the app's well-known folders (AppDataHome, Logs, Packages,
Workflows, Images, ExtensionPacks, and the default Models folder), and
call it whenever the library is found.

It runs after LoadSettings so a ModelDirectoryOverride is known; an
override is never created since it may be on an unmounted drive.
Images/Consolidated is left to the consolidate action, since Images
subfolders show as Outputs categories. Failures are logged, not thrown.

The three TryFindLibrary branches now share LoadLibrary(), and the
Workflows and Outputs pages call EnsureAppDirectories() instead of
creating their own folders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening a folder that doesn't exist threw from shell execute and showed
the exception dialog. Add IOCommands.OpenFolderBrowserAsync and
OpenFileBrowserAsync, which check the path first and show a "Folder not
found" / "File not found" warning instead. They never create anything,
so a genuinely missing package or model folder is reported, not hidden.
The IOCommands browser commands use them.

The Settings > App Folders shortcuts call EnsureAppDirectories() first,
so app folders deleted while running are recreated, then open through
the checked path. A missing ModelDirectoryOverride gets the notification.

CreateLogFolderZip no longer throws if the Logs folder is missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Folders are created where they are used, so TryFindLibrary only finds
and loads the library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@e-nord
e-nord force-pushed the fix-linux-home-dir-log-path branch from 91e4095 to c8bfb57 Compare October 11, 2026 00:38
@e-nord

e-nord commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Valid point. Thought it might be good to enforce certain directories existing as an invariant at startup but probably better to keep the side-effects to a minimum if its too strict or not in the right spot for that and its getting smoothed over on access anyway. I made the corresponding changes, if anything else needs a correction or tweak go right ahead.

@ionite34 ionite34 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, approving :3

@mohnjiles
mohnjiles merged commit 4b0939f into LykosAI:main Oct 11, 2026
3 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants