MuntashirAkon/AppManager · error · IOException

Couldn't delete old file <inputFile>

Error message

Couldn't delete old file <inputFile>

What it means

BackupItems' encryption step writes encrypted copies of each backup file via mCrypto.encrypt and then deletes the original plaintext files. If any Path.delete() returns false the routine throws rather than leaving plaintext files behind.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/BackupItems.java:303

                }
                List<Path> newFileList = new ArrayList<>();
                // Get desired extension
                String ext = CryptoUtils.getExtension(mCryptoMode);
                // Create necessary files (1-1 correspondence)
                for (Path inputFile : files) {
                    Path parent = getBackupPath();
                    String outputFilename = inputFile.getName() + ext;
                    Path outputPath = parent.createNewFile(outputFilename, null);
                    newFileList.add(outputPath);
                    Log.i(TAG, "Input: %s\nOutput: %s", inputFile, outputPath);
                }
                Path[] newFiles = newFileList.toArray(new Path[0]);
                // Perform actual encryption
                mCrypto.encrypt(files, newFiles);
                // Delete unencrypted files
                for (Path inputFile : files) {
                    if (!inputFile.delete()) {
                        throw new IOException("Couldn't delete old file " + inputFile);
                    }
                }
                return newFiles;
            }
        }

        @NonNull
        public Path[] decrypt(@NonNull Path[] files) throws IOException {
            // Decrypt the files but do NOT delete the originals
            synchronized (mCryptoGuard) {
                if (mCrypto == null) {
                    // No encryption enabled
                    return files;
                }
                List<Path> newFileList = new ArrayList<>();
                // Get desired extension
                String ext = CryptoUtils.getExtension(mCryptoMode);
                // Create necessary files (1-1 correspondence)

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check the backup directory is writable (mount flags, SAF permissions) and retry the backup
  2. Delete the file manually and re-run the backup
  3. Move the backup directory to internal app storage
  4. Ensure no other process (file manager, sync app) holds the files open

Example fix

// before
File backupDir = new File(externalStorage, "backups");
// after
File backupDir = new File(context.getFilesDir(), "backups"); // always writable
if (!backupDir.canWrite()) { /* request permissions or pick another dir */ }
Defensive patterns

Strategy: try-catch

Validate before calling

// before backup:
if (!backupDir.canWrite() || backupDir.getFreeSpace() < requiredBytes) {
    // relocate backup storage or request permissions
}

Try / catch

try {
    backup(...);
} catch (IOException e) {
    if (e.getMessage().startsWith("Couldn't delete old file")) {
        // plaintext leftovers remain; clean up and retry
    }
}

Prevention

When it happens

Trigger: Calling encrypt (e.g. through encryptedMetadataFile) on a backup directory where one of the source files cannot be deleted after successful encryption — typically a filesystem/permission problem on the backup storage path.

Common situations: Backing up to SD card/SAF-backed storage with restrictive mount flags, files held open by another process, read-only volume, SELinux denials on external storage.

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/a7f3671360f48b71. Report an issue: GitHub.