Repository navigation
fix(models): install and start on drives without hard links - #10007
Merged
joshistoast merged 6 commits intoOct 25, 2026
Merged
joshistoast merged 6 commits into
joshistoast merged 6 commits into
Conversation
Publish install claims, repaired thumbnails, gallery archives and database copies through one helper that never replaces an existing file. It hard-links where possible, else renames atomically without replacing, else creates exclusively and copies, so exFAT/FAT32 and network drives work. Before, model installs failed with HTTP 500 there and a leftover staging directory stopped the server from starting.
…m-without-hardlinks
joshistoast
reviewed
Oct 25, 2026
joshistoast
requested changes
Oct 25, 2026
joshistoast
left a comment
Collaborator
There was a problem hiding this comment.
A few actionable defects in the copy fallback affecting concurrent replacements, file permissions, and thumbnail rollback.
… installs Two tests wrote a resumable staging marker while the installer's startup restore could still scan it; the restore then claimed or installed the directory first, failing them on slow runners.
…copy fallback A failed copy removes its destination only while it is still the copy it created, and the copy gets the source's permission bits. Publishing returns the published file's signature, so the thumbnail rollback also removes a copied thumbnail and keeps one rewritten in place.
…m-without-hardlinks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On drives without hard links, such as exFAT/FAT32 (common for external drives on Windows) and many network shares, v7.0.0-alpha.3 cannot install models. Every remote install returns HTTP 500 ("Model install failed to start / Internal server error") because the install staging claim is published with
os.link. That call fails on those filesystems:[WinError 1]on Windows,EPERMon Linux. The failed install also leaves amodels/tmpinstall_*directory behind. Startup cleanup then claims that directory the same way, so the server stops starting at all (Application startup failed).Thumbnail repair, gallery archive and restore, and
invokeai-db-copypublish files the same way, so they break on those filesystems too.All of these now go through one helper,
invokeai/app/util/no_replace.py.publish_noreplacenever replaces an existing file, and it tries three methods in order:renameat2(RENAME_NOREPLACE)on Linux,renamex_np(RENAME_EXCL)on macOS,os.renameon Windows. This is what fixes exFAT and FAT32.O_EXCL) plus copy. For mounts that support neither, such as macOS exFAT, NFS, 9p and FUSE.rename_noreplaceis the existingModelInstallService._rename_noreplace, moved into the helper.invokeai-db-copyloses its racy exists-check plusos.replacefallback.Related Issues / Discussions
Reported on Discord: "Alpha 3 errors out when I try to install new models." Install requests return 500, and the launcher shows
Exception in ASGI applicationwith a traceback throughmodel_install_default.py.QA Instructions
Reproduced and verified on a real exFAT volume on Linux, with the Invoke root on that volume:
POST /api/v2/models/install?source=stabilityai/sd-vae-ft-msereturns 500, ending inPermissionError: [Errno 1] Operation not permittedfromos.linkin_claim_install_tmpdir.models/tmpinstall_*, startup exits with code 3 (Application startup failed).os.linkfails with EPERM;renameat2(RENAME_NOREPLACE)succeeds and returns EEXIST when the target exists.test_no_replace.py,test_install_staging_ledger.py,test_model_install.py,test_image_files_disk.py,test_gallery_maintenance_service.pyandtest_database_copy.py; all pass.os.link.os.link(EPERM) andrename_noreplace(ENOTSUP). The fallback therefore runs against each CI runner's real rename.invokeai-db-copyis covered only by the helper's tests, because its end-to-end tests needINVOKEAI_TEST_DB_URL.ruff checkandruff format --checkpass on the changed files. I left the full suite to CI.Review
The review led to two changes:
invokeai-db-copyon those mounts.Remaining limitations:
Checklist
What's Newcopy (if doing a release after this PR)Need help on this PR? Tag
@codesmith-botwith what you need.