MuntashirAkon/AppManager · error · JSONException
Empty JSON string.
Error message
Empty JSON string.
What it means
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.
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
Example fix
// caller-side guard
String json = logFile.getContentAsString();
if (json == null || json.trim().isEmpty()) {
// skip this package; do not call convert()
return;
}
converter.convert(); Defensive patterns
Strategy: validation
Validate before calling
Path logFile = backupLocation.findFile(packageName + ".log");
String s = logFile.getContentAsString();
if (s == null || s.trim().isEmpty()) {
throw new IllegalStateException("OAB log empty for " + packageName + "; re-create backup");
} Type guard
static boolean isValidOabLog(String s) {
if (s == null || s.trim().isEmpty()) return false;
try {
JSONObject o = new JSONObject(s);
return o.has("label") && o.has("packageName") && o.has("versionName") && o.has("versionCode");
} catch (JSONException e) { return false; }
} Try / catch
try {
converter.convert();
} catch (JSONException | BackupException e) {
if ("Empty JSON string.".equals(e.getMessage())) {
// skip this package or re-run the original OAndBackup backup
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Interrupted OAndBackup run left an empty log; user copied backup folders partially; wrong package directory selected for conversion.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Cannot convert special backup " + mPackageName
- Could not finalise backup.
- Could not get backup files.
- Could not read backup info. Possibly due to a malformed…
- Could not read backup metadata. Possibly due to a malformed…
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/68c73e46614c32b3.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/OABConverter.java:190
}
@Override
public void cleanup() {
mSourceCrypto.close();
mBackupLocation.delete();
}
@Override
public String getPackageName() {
return mPackageName;
}
private BackupMetadataV2 readLogFile() throws BackupException {
try {
BackupMetadataV2 metadataV2 = new BackupMetadataV2();
Path logFile = mBackupLocation.findFile(mPackageName + ".log");
String jsonString = logFile.getContentAsString();
if (TextUtils.isEmpty(jsonString)) throw new JSONException("Empty JSON string.");
JSONObject jsonObject = new JSONObject(jsonString);
metadataV2.label = jsonObject.getString("label");
metadataV2.packageName = jsonObject.getString("packageName");
metadataV2.versionName = jsonObject.getString("versionName");
metadataV2.versionCode = jsonObject.getInt("versionCode");
metadataV2.isSystem = jsonObject.optBoolean("isSystem");
metadataV2.isSplitApk = false;
metadataV2.splitConfigs = ArrayUtils.emptyArray(String.class);
metadataV2.hasRules = false;
metadataV2.backupTime = jsonObject.getLong("lastBackupMillis");
metadataV2.crypto = jsonObject.optBoolean("isEncrypted") ? CryptoUtils.MODE_OPEN_PGP : CryptoUtils.MODE_NO_ENCRYPTION;
mSourceCryptoMode = metadataV2.crypto;
mSourceCrypto = CryptoUtils.setupCrypto(metadataV2);
metadataV2.apkName = new File(jsonObject.getString("sourceDir")).getName();
// Flags
metadataV2.flags = new BackupFlags(BackupFlags.BACKUP_MULTIPLE);
int backupMode = jsonObject.optInt("backupMode", MODE_UNSET);
if (backupMode == MODE_UNSET) {View on GitHub (pinned to 0152f468fc)