MuntashirAkon/AppManager · error · BackupException

Could not finalise backup.

Error message

Could not finalise backup.

What it means

SBConverter.convert throws BackupException('Could not finalise backup.') when mBackupItem.commit() throws IOException. Commit atomically replaces the staging backup with the final backup; failure here means the backup files exist but were not promoted, so conversion reports failure.

Solutions

  1. Delete any pre-existing/conflicting backup with the same name and retry
  2. Check free space and writability of the final backup location
  3. Inspect the wrapped IOException cause for the exact move/rename error
  4. Retry conversion; leftover staging is cleaned up in the finally block
Defensive patterns

Strategy: retry

Validate before calling

// ensure no conflicting final backup exists before commit
File finalDir = new File(BackupUtils.getBackupPath(mUserId, mPackageName, mDestMetadata.backupName));
if (finalDir.exists()) {
    throw new IOException("Conflicting backup already exists at " + finalDir);
}

Try / catch

try {
    converter.convert(...);
} catch (BackupException e) {
    if ("Could not finalise backup.".equals(e.getMessage())) {
        // staging was cleaned up; resolve conflict/free space and retry conversion
    }
}

Prevention

When it happens

Trigger: commit() fails renaming/moving staged backup files into place: destination directory conflicts, cross-filesystem moves, unwritable target, or I/O errors during the move.

Common situations: Existing backup with the same name blocking the commit; storage full; Android file APIs failing across mount points; stale staging directories.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/af11f386a1f87493. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/SBConverter.java:147

                Map<String, String> filenameChecksumMap = MetadataManager.writeMetadata(mDestMetadata, mBackupItem);
                for (Map.Entry<String, String> filenameChecksumPair : filenameChecksumMap.entrySet()) {
                    mChecksum.add(filenameChecksumPair.getKey(), filenameChecksumPair.getValue());
                }
            } catch (IOException e) {
                throw new BackupException("Failed to write metadata.");
            }
            mChecksum.close();
            // Encrypt checksum
            try {
                mBackupItem.encrypt(new Path[]{mChecksum.getFile()});
            } catch (IOException e) {
                throw new BackupException("Failed to encrypt checksums.txt");
            }
            // Replace current backup
            try {
                mBackupItem.commit();
            } catch (IOException e) {
                throw new BackupException("Could not finalise backup.", e);
            }
            backupSuccess = true;
        } catch (BackupException e) {
            throw e;
        } catch (Throwable th) {
            throw new BackupException("Unknown error occurred.", th);
        } finally {
            mBackupItem.cleanup();
            mCachedApk.requireParent().delete();
            if (backupSuccess) {
                BackupUtils.putBackupToDbAndBroadcast(ContextUtils.getContext(), mDestMetadata);
            }
        }
    }

    @Override
    public void cleanup() {
        for (Path file : mFilesToBeDeleted) {

View on GitHub (pinned to 0152f468fc)