MuntashirAkon/AppManager · error · java.io.IOException

Invalid value for key: ${name} (value: ${value})

Error message

Invalid value for key: ${name} (value: ${value})

What it means

IOException thrown by SharedPrefsUtil.writeSharedPref when the value passed for a preference key is not one of the serializable types the writer supports (String, Set<String>, etc.). The Android SharedPreferences XML format is type-tagged, so an unsupported value type cannot be represented and serialization of the whole file is aborted to avoid producing a corrupt XML.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/sharedpref/SharedPrefsUtil.java:147

                xmlSerializer.attribute("", "value", value.toString());
                xmlSerializer.endTag("", TAG_LONG);
            } else if (value instanceof String) {
                xmlSerializer.startTag("", TAG_STRING);
                xmlSerializer.attribute("", "name", name);
                xmlSerializer.text(value.toString());
                xmlSerializer.endTag("", TAG_STRING);
            } else if (value instanceof Set) {
                xmlSerializer.startTag("", TAG_SET);
                xmlSerializer.attribute("", "name", name);
                //noinspection unchecked
                for (String v : (Set<String>) value) {
                    xmlSerializer.startTag("", TAG_STRING);
                    xmlSerializer.text(v);
                    xmlSerializer.endTag("", TAG_STRING);
                }
                xmlSerializer.endTag("", TAG_SET);
            } else {
                throw new IOException("Invalid value for key: " + name + " (value: " + value + ")");
            }
        }
        xmlSerializer.endTag("", TAG_ROOT);
        xmlSerializer.endDocument();
        xmlSerializer.flush();
        os.write(stringWriter.toString().getBytes());
    }

    @NonNull
    public static String flattenToString(@NonNull Set<String> stringSet) {
        List<String> stringList = new ArrayList<>(stringSet.size());
        for (String string : stringSet) {
            stringList.add(string.replace(",", "\\,"));
        }
        return TextUtils.join(",", stringList);
    }

    @NonNull

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Convert all values to String (or Set<String>) before passing the map to writeSharedPref
  2. Extend the writer with branches for the additional types you need (int, boolean, long, float)
  3. Validate the map types before calling and reject/log unsupported entries early
  4. Wrap the call in try-catch for IOException and report which key failed using the message's key name

Example fix

// before
Map<String, Object> prefs = new HashMap<>();
prefs.put("retry_count", 3);
writeSharedPref(os, prefs);
// after
Map<String, Object> prefs = new HashMap<>();
prefs.put("retry_count", String.valueOf(3));
writeSharedPref(os, prefs);
Defensive patterns

Strategy: validation

Validate before calling

for (Map.Entry<String, Object> e : prefs.entrySet()) {
    Object v = e.getValue();
    if (!(v instanceof String) && !(v instanceof Set)) {
        throw new IllegalArgumentException("Unsupported value for " + e.getKey());
    }
}

Type guard

static boolean isSerializablePref(Object v) {
    return v instanceof String || (v instanceof Set<?> s && s.stream().allMatch(String.class::isInstance));
}

Try / catch

try {
    SharedPrefsUtil.writeSharedPref(os, prefs);
} catch (IOException e) {
    Log.e(TAG, "Pref write failed: " + e.getMessage(), e); // message names the offending key
}

Prevention

When it happens

Trigger: Calling writeSharedPref (or the higher-level setPreference API) with a Map containing a key whose value is an Integer, Boolean, Long, Float, byte[], or any other non-String/non-Set object; the if/else chain over value types exhausts and hits the final else throw.

Common situations: Importing preferences from JSON where numbers stay parsed as Integer instead of String; programmatically constructing the prefs map and forgetting to stringify values; version drift where a new pref type was added upstream without extending the writer.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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