{"record":{"id":"49d2ee0d1b1aa33d","repo":"MuntashirAkon/AppManager","slug":"for-file","errorCode":null,"errorMessage":" for file ","messagePattern":" for file ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/MetadataManager.java","lineNumber":143,"sourceCode":"            // Info is a subset of meta_v2.am.json except for backup_name\n            metadataObject.remove(\"backup_name\");\n            outputStream.write(metadataObject.toString(4).getBytes());\n            return Collections.singletonMap(metadataFile.getName(), DigestUtils.getHexDigest(\n                    metadata.info.checksumAlgo, metadataFile));\n        } catch (JSONException e) {\n            throw new IOException(e.getMessage() + \" for path \" + backupFile.getBackupPath(), e);\n        }\n    }\n\n    @WorkerThread\n    @NonNull\n    private static Map<String, String> writeMetadataV5(@NonNull BackupMetadataV5 metadata, @NonNull BackupItems.BackupItem backupFile) throws IOException {\n        Map<String, String> filenameChecksumMap = new LinkedHashMap<>(2);\n        Path metadataFile = backupFile.getMetadataV5File(true);\n        try (OutputStream outputStream = metadataFile.openOutputStream()) {\n            outputStream.write(metadata.metadata.serializeToJson().toString(4).getBytes());\n        } catch (JSONException e) {\n            throw new IOException(e.getMessage() + \" for file \" + metadataFile, e);\n        }\n        // Encrypt the metadata\n        Path encryptedMetadataFile = backupFile.encrypt(new Path[]{metadataFile})[0];\n        filenameChecksumMap.put(encryptedMetadataFile.getName(), DigestUtils.getHexDigest(\n                metadata.info.checksumAlgo, encryptedMetadataFile));\n        Path infoFile = backupFile.getInfoFile();\n        try (OutputStream outputStream = infoFile.openOutputStream()) {\n            outputStream.write(metadata.info.serializeToJson().toString(4).getBytes());\n            filenameChecksumMap.put(infoFile.getName(), DigestUtils.getHexDigest(\n                    metadata.info.checksumAlgo, infoFile));\n        } catch (JSONException e) {\n            throw new IOException(e.getMessage() + \" for file \" + infoFile, e);\n        }\n        return filenameChecksumMap;\n    }\n\n    private static void setCrypto(@NonNull BackupItems.BackupItem backupItem, @NonNull BackupMetadataV5.Info backupInfo) throws IOException {\n        if (!CryptoUtils.isAvailable(backupInfo.crypto)) {","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/MetadataManager.java#L125-L161","documentation":"writeMetadataV5 writes meta_v5.am.json by serializing metadata.metadata via serializeToJson(); any JSONException is rethrown as IOException with the metadata file path appended, indicating the v5 metadata document could not be serialized to JSON.","triggerScenarios":"Calling writeMetadata for a v5+ backup when metadata.metadata.serializeToJson() throws — typically null or invalid field values inside the Metadata object.","commonSituations":"Programmatically constructed Metadata objects with missing/invalid fields (e.g. null timestamps or names placed where JSONObject.put rejects them), or corrupted in-memory metadata after partial deserialization.","solutions":["Inspect the JSONException cause to find the field that failed to serialize and populate it with a valid value.","Validate the Metadata object (required fields non-null) before calling writeMetadata.","Reload the metadata from the source backup to recover a consistent in-memory object."],"exampleFix":"// before\nMetadataManager.writeMetadata(metadata, backupFile);\n// after\nif (metadata.metadata == null) {\n    throw new IllegalArgumentException(\"Metadata body is null\");\n}\nMetadataManager.writeMetadata(metadata, backupFile);","handlingStrategy":"validation","validationCode":"if (metadata.metadata == null || metadata.info == null) {\n    throw new IllegalArgumentException(\"Incomplete BackupMetadataV5\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    MetadataManager.writeMetadata(metadata, backupFile);\n} catch (IOException e) {\n    if (e.getCause() instanceof JSONException) {\n        // fix the offending Metadata field reported by the cause\n    } else throw e;\n}","preventionTips":["Validate required Metadata fields before calling writeMetadata.","Test serializeToJson() on constructed metadata in unit tests.","Round-trip (write then read) metadata in tests to catch serialization issues."],"tags":["backup","json","serialization","io"],"backgroundTag":"json-serialization-failed","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"}