microg/GmsCore · error · IllegalArgumentException
Not a String type
Error message
Not a String type
What it means
Flag.getString() throws IllegalArgumentException("Not a String type") when the flag's dataType is not DATA_TYPE_STRING. Flag is a tagged union, and the string accessor refuses to return stringValue unless the discriminator matches, preventing silent misreads of non-string flags.
Source
Thrown at play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java:89
throw new IllegalArgumentException("Not a long type");
}
public boolean getBool() {
if (dataType == DATA_TYPE_BOOL)
return boolValue;
throw new IllegalArgumentException("Not a boolean type");
}
public double getDouble() {
if (dataType == DATA_TYPE_DOUBLE)
return doubleValue;
throw new IllegalArgumentException("Not a double type");
}
public String getString() {
if (dataType == DATA_TYPE_STRING)
return stringValue;
throw new IllegalArgumentException("Not a String type");
}
public byte[] getBytes() {
if (dataType == DATA_TYPE_BYTES)
return bytesValue;
throw new IllegalArgumentException("Not a bytes type");
}
public static final int DATA_TYPE_LONG = 1;
public static final int DATA_TYPE_BOOL = 2;
public static final int DATA_TYPE_DOUBLE = 3;
public static final int DATA_TYPE_STRING = 4;
public static final int DATA_TYPE_BYTES = 5;
public static final Creator<Flag> CREATOR = findCreator(Flag.class);
}
View on GitHub (pinned to 157c9d86ac)
Solutions
- Guard with flag.getDataType() == Flag.DATA_TYPE_STRING before calling getString()
- In generic conversion code, switch over DATA_TYPE_* and convert each type to string explicitly (String.valueOf / Arrays.toString)
- Verify the server-side flag is still a string type
- Catch IllegalArgumentException when deserializing untrusted flag data
Example fix
// before String s = flag.getString(); // after String s = flag.getDataType() == Flag.DATA_TYPE_STRING ? flag.getString() : null;
Defensive patterns
Strategy: type-guard
Validate before calling
if (flag.getDataType() != Flag.DATA_TYPE_STRING) { throw new IllegalStateException("flag is not a string: " + flag.getDataType()); } Type guard
static boolean isStringFlag(Flag f) { return f != null && f.getDataType() == Flag.DATA_TYPE_STRING; } Try / catch
try { String v = flag.getString(); } catch (IllegalArgumentException e) { log.warn("Flag type mismatch", e); v = null; } Prevention
- Check dataType == DATA_TYPE_STRING before getString()
- In generic conversions, stringify each type via its own getter, not getString() unconditionally
- Never assume config values are strings across library or protocol changes
- Handle nulls and unexpected types when building flag maps
When it happens
Trigger: Calling Flag.getString() on a Flag whose dataType is DATA_TYPE_LONG (1), DATA_TYPE_BOOL (2), DATA_TYPE_DOUBLE (3), or DATA_TYPE_BYTES (5) instead of DATA_TYPE_STRING (4).
Common situations: Treating a numeric/boolean experiment flag as a string (e.g. for feature parameters); server-side flag retyped from string to long; blanket flag-to-map conversion code that calls getString() on every entry.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/22e89a6768443a17.
Report an issue: GitHub.