Skip to content

Count an archive that is already gone as deleted - #508

Open
Pixnop wants to merge 1 commit into
devfrom
fix/backup-limit-refusal
Open

Pixnop wants to merge 1 commit into
devfrom
fix/backup-limit-refusal

Conversation

@Pixnop

@Pixnop Pixnop commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

What the player sees

An Installation with a Backups max amount of 6 refuses every backup:

No backup made: an old backup could not be removed to make room for the new one.

Raising the limit to 7 makes the same backup go through. The player had four archives in their Backups folder, so the sentence reads as a limit that is one too low.

Why

A backup record whose archive is no longer on disk can never be deleted, and it keeps its slot under the limit.

DELETE_PATH runs the path through assertManagedDeletionPath, which asserts it with allowMissing: false (src/ipc/pathPolicy.ts:196), so a file that is not there throws and the handler answers false (src/ipc/handlers/pathsHandlers.ts:278-285). The domain read that single false as "the file is still there" (src/domain/installations/backupDeletion.ts:29 before this change).

The prune starts as soon as the record count reaches the limit (src/domain/installations/backup.ts:110) and gives the whole backup up at the first refusal (src/domain/installations/backup.ts:124), which the renderer turns into the sentence above (src/renderer/src/features/installations/adapters/backupFailure.ts:64). Raising the limit above the record count skips the prune entirely, which is the part that made it look like a limit problem.

Reproduction: six records with a limit of 6, the two oldest archives deleted from the Backups folder by hand, four archives left on disk. The backup is refused at 6 and made at 7.

Two other callers of the same function were wrong in the same way, so the fix sits in the function they share: the delete button on the Manage Backups page left the row there for good, and deleting an Installation with its data reported the missing archive as one it had to leave behind.

The refusal that is left over is a file that really is there and really will not go, so pruneFailed now says what to check, in en-US and fr-FR.

Testing

  • tests/domain/installations/backup.test.ts: the reported shape, six records at a limit of 6 with the two oldest archives gone, backup made and the stale record reported as deleted. Red before the change with prune-failed.
  • tests/domain/installations/backupDeletion.test.ts: an archive that is no longer on disk counts as deleted. The existing case, a file that is there and will not go, still answers file-delete-failed.
  • tests/renderer-dom/useMakeInstallationBackup.test.tsx: the same situation end to end through the hook, asserting the record leaves the Installation and the player reads no refusal.
  • installationsRestoreBackup.test.tsx now says the archive is on disk in the case that pins a real delete failure, otherwise the refusal it tests is no longer a refusal.
  • Mutation check: reverting backupDeletion.ts alone turns all three new tests red, restoring it turns them green.
  • npm run typecheck, npm run lint:ci (0 errors, 14 pre-existing warnings), npm run format:check, npm run test:coverage (242 files, 4465 passed).

Closes #507. Reported on Discord by NekoJess.

A backup record whose file is no longer in the Backups folder could never be
removed. The host refuses a deletion path it cannot find, since
assertManagedDeletionPath asserts it with allowMissing false, and the domain
read that single false as "the file is still there".

The record then kept its slot under the Installation's limit. Once the records
reached that limit the prune had to remove the oldest one, failed on the file
that was not there, and refused the whole backup with a sentence about making
room for the new one. Raising the limit above the record count skipped the prune
entirely, which is why it looked like a limit that was too low.

A file that is not on disk counts as deleted now, so the record comes off with
it and stops taking a slot. Two other paths go through the same function and
were wrong in the same way: the delete button on the Manage Backups page left
the row there for good, and deleting an Installation with its data reported the
missing archive as one it had to leave behind.

The refusal that is left over is a file that really is there and really will not
go, so it now says what to check, in en-US and fr-FR.

Closes #507.
@Pixnop
Pixnop requested a review from Zaldaryon September 18, 2026 16:48
@github-actions

Copy link
Copy Markdown

Translation status

en-US is the source and carries 874 keys.

Locale Keys Missing Stale Drafted to review
be-BY 882 0 8 645
de-DE 874 0 0 725
es-ES 878 0 4 532
fr-FR 878 0 4 0
hu-HU 874 0 0 600
it-IT 878 0 4 539
nl-NL 874 0 0 725
pl-PL 882 0 8 536
pt-BR 878 0 4 475
pt-PT 878 0 4 549
ru-RU 882 0 8 633
uk-UA 882 0 8 558
zh-CN 874 0 0 715

The status page is out of date. Refresh it with npm run i18n:status -- --write docs/contribute/translation-status.md.

Drafted values are the machine-drafted ones still waiting for a native review, listed per locale in src/renderer/src/locales/drafted.json. See #496.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant