MuntashirAkon/AppManager · error

Empty profile path

Error message

Empty profile path

What it means

BaseProfile.fromPath is annotated @Contract("null -> fail"): it requires a non-null Path to a profile JSON file. Passing null gives it nothing to read, so it throws IOException('Empty profile path') before attempting to deserialize.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/profiles/struct/BaseProfile.java:38

import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

import io.github.muntashirakon.AppManager.history.IJsonSerializer;
import io.github.muntashirakon.AppManager.history.JsonDeserializer;
import io.github.muntashirakon.AppManager.profiles.ProfileLogger;
import io.github.muntashirakon.AppManager.profiles.ProfileManager;
import io.github.muntashirakon.AppManager.progress.ProgressHandler;
import io.github.muntashirakon.AppManager.utils.JSONUtils;
import io.github.muntashirakon.io.Path;
import io.github.muntashirakon.io.Paths;
import io.github.muntashirakon.util.LocalizedString;

public abstract class BaseProfile implements LocalizedString, IJsonSerializer {
    @Contract("null -> fail")
    @NonNull
    public static BaseProfile fromPath(@Nullable Path profilePath) throws IOException, JSONException {
        if (profilePath == null) {
            throw new IOException("Empty profile path");
        }
        String profileStr = profilePath.getContentAsString();
        JSONObject profileObj = new JSONObject(profileStr);
        return BaseProfile.DESERIALIZER.deserialize(profileObj);
    }

    @NonNull
    public static BaseProfile newProfile(@NonNull String newProfileName, int type, @Nullable BaseProfile source) {
        String profileId = ProfileManager.getProfileIdCompat(newProfileName);
        // TODO: 17/9/23 TODO: Remove these once we migrated to UUID based profile ID
        // BEGIN legacy: For legacy profile, the generated ID can be the same as an existing profile
        Path profilesDir = ProfileManager.getProfilesDir();
        Path profilePath = Paths.build(profilesDir, profileId + PROFILE_EXT);
        String profileName = newProfileName;
        int i = 1;
        while (profilePath != null && profilePath.exists()) {
            // Try another name
            profileName = newProfileName + " (" + i + ")";

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Check that the profile Path exists and is non-null before calling fromPath
  2. Fix the upstream lookup that produced the null Path (wrong profile name or missing profiles directory)
  3. Catch IOException around fromPath if null paths are legitimately possible in your flow

Example fix

// before
BaseProfile profile = BaseProfile.fromPath(lookupProfile(name));
// after
Path path = lookupProfile(name);
if (path == null) {
    throw new FileNotFoundException("Profile not found: " + name);
}
BaseProfile profile = BaseProfile.fromPath(path);
Defensive patterns

Strategy: validation

Validate before calling

if (profilePath == null || !Files.exists(profilePath)) {
    throw new FileNotFoundException("Profile not found: " + profilePath);
}

Type guard

@Nullable Path resolveProfile(String name) {
    Path p = profilesDir.resolve(name + PMF_EXT);
    return Files.exists(p) ? p : null;
}
// caller: only call fromPath when resolveProfile != null

Try / catch

try {
    BaseProfile profile = BaseProfile.fromPath(path);
} catch (IOException | JSONException e) {
    showError("Cannot load profile: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling BaseProfile.fromPath(null), typically when a profile file path lookup failed upstream and the null result was passed through unguarded.

Common situations: Profile name typo causing a directory-listing lookup to return null; calling the API before the profiles directory exists; migrating code that previously used names instead of Path objects.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/ed976f0f2ff43038. Report an issue: GitHub.