{"record":{"id":"68c73e46614c32b3","repo":"MuntashirAkon/AppManager","slug":"empty-json-string","errorCode":null,"errorMessage":"Empty JSON string.","messagePattern":"Empty JSON string\\.","errorType":"exception","errorClass":"JSONException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java","lineNumber":190,"sourceCode":"    }\n\n    @Override\n    public void cleanup() {\n        mSourceCrypto.close();\n        mBackupLocation.delete();\n    }\n\n    @Override\n    public String getPackageName() {\n        return mPackageName;\n    }\n\n    private BackupMetadataV2 readLogFile() throws BackupException {\n        try {\n            BackupMetadataV2 metadataV2 = new BackupMetadataV2();\n            Path logFile = mBackupLocation.findFile(mPackageName + \".log\");\n            String jsonString = logFile.getContentAsString();\n            if (TextUtils.isEmpty(jsonString)) throw new JSONException(\"Empty JSON string.\");\n            JSONObject jsonObject = new JSONObject(jsonString);\n            metadataV2.label = jsonObject.getString(\"label\");\n            metadataV2.packageName = jsonObject.getString(\"packageName\");\n            metadataV2.versionName = jsonObject.getString(\"versionName\");\n            metadataV2.versionCode = jsonObject.getInt(\"versionCode\");\n            metadataV2.isSystem = jsonObject.optBoolean(\"isSystem\");\n            metadataV2.isSplitApk = false;\n            metadataV2.splitConfigs = ArrayUtils.emptyArray(String.class);\n            metadataV2.hasRules = false;\n            metadataV2.backupTime = jsonObject.getLong(\"lastBackupMillis\");\n            metadataV2.crypto = jsonObject.optBoolean(\"isEncrypted\") ? CryptoUtils.MODE_OPEN_PGP : CryptoUtils.MODE_NO_ENCRYPTION;\n            mSourceCryptoMode = metadataV2.crypto;\n            mSourceCrypto = CryptoUtils.setupCrypto(metadataV2);\n            metadataV2.apkName = new File(jsonObject.getString(\"sourceDir\")).getName();\n            // Flags\n            metadataV2.flags = new BackupFlags(BackupFlags.BACKUP_MULTIPLE);\n            int backupMode = jsonObject.optInt(\"backupMode\", MODE_UNSET);\n            if (backupMode == MODE_UNSET) {","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java#L172-L208","documentation":"readLogFile reads the OAndBackup `<package>.log` file and parses it as JSON. If the file content is empty or whitespace-only, it throws JSONException(\"Empty JSON string.\") which propagates as a BackupException. The log file must contain a valid JSON object with label/packageName/versionName/versionCode.","triggerScenarios":"mBackupLocation.findFile(mPackageName + \".log\") returns a 0-byte (or blank) file — the OAndBackup log was never written, was truncated, or points at the wrong file.","commonSituations":"Interrupted OAndBackup run left an empty log; user copied backup folders partially; wrong package directory selected for conversion.","solutions":["Check the <package>.log file size and content — re-create the OAndBackup backup if it is empty","Ensure you are converting the correct backup directory containing a complete log file","Re-run the original OAndBackup backup, then convert again"],"exampleFix":"// caller-side guard\nString json = logFile.getContentAsString();\nif (json == null || json.trim().isEmpty()) {\n    // skip this package; do not call convert()\n    return;\n}\nconverter.convert();","handlingStrategy":"validation","validationCode":"Path logFile = backupLocation.findFile(packageName + \".log\");\nString s = logFile.getContentAsString();\nif (s == null || s.trim().isEmpty()) {\n    throw new IllegalStateException(\"OAB log empty for \" + packageName + \"; re-create backup\");\n}","typeGuard":"static boolean isValidOabLog(String s) {\n    if (s == null || s.trim().isEmpty()) return false;\n    try {\n        JSONObject o = new JSONObject(s);\n        return o.has(\"label\") && o.has(\"packageName\") && o.has(\"versionName\") && o.has(\"versionCode\");\n    } catch (JSONException e) { return false; }\n}","tryCatchPattern":"try {\n    converter.convert();\n} catch (JSONException | BackupException e) {\n    if (\"Empty JSON string.\".equals(e.getMessage())) {\n        // skip this package or re-run the original OAndBackup backup\n    }\n}","preventionTips":["Verify the .log file is non-empty before conversion","Re-create OAndBackup backups whose log is truncated","Select the correct backup directory for the package"],"tags":["json","backup","migration","empty-input"],"backgroundTag":"empty-required-field","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}