{"record":{"id":"3929aa8a7f69e805","repo":"MuntashirAkon/AppManager","slug":"rules-file-is-missing-verifyop","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/VerifyOp.java","lineNumber":218,"sourceCode":"            // There are no permissions, just skip\n            return;\n        }\n        String checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, miscFile);\n        if (!checksum.equals(mChecksum.get(miscFile.getName()))) {\n            throw new BackupException(\"Could not verify extras.\" +\n                    \"\\nFile: \" + miscFile.getName() +\n                    \"\\nFound: \" + checksum +\n                    \"\\nRequired: \" + mChecksum.get(miscFile.getName()));\n        }\n    }\n\n    private void verifyRules() throws BackupException {\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        String checksum = DigestUtils.getHexDigest(mBackupInfo.checksumAlgo, rulesFile);\n        if (!checksum.equals(mChecksum.get(rulesFile.getName()))) {\n            throw new BackupException(\"Could not verify rules file.\" +\n                    \"\\nFile: \" + rulesFile.getName() +\n                    \"\\nFound: \" + checksum +\n                    \"\\nRequired: \" + mChecksum.get(rulesFile.getName()));\n        }\n    }\n}","sourceCodeStart":200,"sourceCodeEnd":232,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/VerifyOp.java#L200-L232","documentation":"verifyRules() cannot obtain the backup's rules file (mBackupItem.getRulesFile() throws IOException) while mBackupMetadata.hasRules is true — the metadata declares that rules were backed up (e.g. net-policy/ifw rules), but the actual rules file is absent from the backup directory. If hasRules were false, a missing rules file is expected and silently skipped.","triggerScenarios":"verify() -> verifyRules() when mBackupFlags.backupRules() is set; getRulesFile() throws IOException AND mBackupMetadata.hasRules == true — a declared rules file that is missing on disk.","commonSituations":"Rules file (e.g. ifw/net-policy XML) deleted or not copied when moving the backup folder; backup interrupted before the rules step finished writing yet metadata still recorded hasRules=true; selective file sync (cloud) skipped the small rules file.","solutions":["Copy the missing rules file from the original backup into the backup directory.","Recreate the backup ensuring it completes the rules step.","If rules aren't needed, clear the hasRules flag in the metadata (with matching checksum update) or unset the backupRules flag so verification skips it.","Inspect the cause IOException for permission/path issues in the backup directory."],"exampleFix":"// before\n//   Rules file is missing. (metadata.hasRules = true, file absent)\n// after: copy the rules file back, or set hasRules=false when no rules exist\n// metadata.hasRules = false; // + update metadata checksum entry","handlingStrategy":"validation","validationCode":"// Ensure declared rules file exists before verify\nif (flags.backupRules() && metadata.hasRules) {\n    try {\n        backupItem.getRulesFile();\n    } catch (IOException e) {\n        throw new IllegalStateException(\"rules file declared but missing: copy it back or set hasRules=false\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    verifyOp.verify();\n} catch (BackupException e) {\n    if (e.getMessage().equals(\"Rules file is missing.\")) {\n        // re-copy the rules file or clear hasRules in metadata (and update checksums)\n    }\n}","preventionTips":["When copying backups, include small auxiliary files (rules, misc) — they are easy to miss with selective sync.","Discard and redo backups that were interrupted mid-write; metadata may claim hasRules without the file.","If you don't need rules, disable the rules backup flag rather than deleting the file afterwards.","Keep metadata (hasRules flag) and files consistent: change them together."],"tags":["backup","rules","missing-files","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"}