{"record":{"id":"b22198cfa157d2bd","repo":"MuntashirAkon/AppManager","slug":"rules-file-is-missing","errorCode":null,"errorMessage":"Rules file is missing.","messagePattern":"Rules file is missing\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":762,"sourceCode":"        }\n        try {\n            rules.loadExternalEntries(miscFile);\n        } catch (Throwable e) {\n            throw new BackupException(\"Failed to load rules from misc.\", e);\n        }\n    }\n\n    private void restoreRules() throws BackupException {\n        // Apply rules\n        if (!mIsInstalled) {\n            throw new BackupException(\"Rules restore is requested but the app isn't installed.\");\n        }\n        Path rulesFile;\n        try {\n            rulesFile = mBackupItem.getRulesFile();\n        } catch (IOException e) {\n            if (mBackupMetadata.hasRules) {\n                throw new BackupException(\"Rules file is missing.\", e);\n            } else {\n                // There are no rules, just skip\n                return;\n            }\n        }\n        if (!mRequestedFlags.skipSignatureCheck()) {\n            String checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, rulesFile);\n            if (!checksum.equals(mChecksum.get(rulesFile.getName()))) {\n                throw new BackupException(\"Couldn't verify permission file.\" +\n                        \"\\nFile: \" + rulesFile +\n                        \"\\nFound: \" + checksum +\n                        \"\\nRequired: \" + mChecksum.get(rulesFile.getName()));\n            }\n        }\n        // Decrypt rules file\n        try {\n            rulesFile = mBackupItem.decrypt(new Path[]{rulesFile})[0];\n        } catch (IOException | IndexOutOfBoundsException e) {","sourceCodeStart":744,"sourceCodeEnd":780,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L744-L780","documentation":"Thrown by restoreRules when reading the backup's rules file via mBackupItem.getRulesFile() throws IOException while the backup metadata claims hasRules == true. In other words, the metadata says rules exist, but the actual rules archive/file cannot be found or read, so the restore cannot proceed silently.","triggerScenarios":"getRulesFile() throws IOException (file missing from backup dir, unreadable path) AND mBackupMetadata.hasRules is true — an inconsistency between metadata and actual backup contents.","commonSituations":"Rules file (rules.json / rules archive) was not copied with the backup; backup partially transferred; metadata edited or stale after files were removed; storage permission issues making the file unreadable.","solutions":["Re-copy the complete backup directory including the rules file","If the rules file is intentionally absent, fix/clear hasRules in Metadata.json or use a backup without the rules flag","Skip the rules-restore option and apply rules manually after data restore","Check storage permissions/paths so getRulesFile() can actually read the backup location"],"exampleFix":"// before\nif (mBackupMetadata.hasRules) {\n    throw new BackupException(\"Rules file is missing.\", e);\n}\n// after\nif (mBackupMetadata.hasRules) {\n    Log.w(TAG, \"Metadata says rules exist but the file is missing; skipping rules restore\", e);\n    return;\n}","handlingStrategy":"validation","validationCode":"File rulesFile = new File(backupDir, \"rules.json\");\nif (metadata.hasRules && !rulesFile.exists()) {\n    flags.restoreRules = false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    restoreOp.runRestore();\n} catch (BackupException e) {\n    if (\"Rules file is missing.\".equals(e.getMessage())) {\n        Log.w(TAG, \"Rules file missing; continuing without rules\", e.getCause());\n    } else throw e;\n}","preventionTips":["Always transfer the entire backup folder","Regenerate Metadata.json when manually altering backups","Verify backup completeness before restoring","Keep backup directories accessible with correct permissions"],"tags":["android","backup","rules","missing-file","metadata"],"backgroundTag":"file-not-found","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}