{"record":{"id":"49d06e690ad3fd34","repo":"microg/GmsCore","slug":"not-a-long-type","errorCode":null,"errorMessage":"Not a long type","messagePattern":"Not a long type","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java","lineNumber":71,"sourceCode":"\n    public Flag(String name, String stringValue, int flagType) {\n        this.name = name;\n        this.stringValue = stringValue;\n        this.dataType = DATA_TYPE_STRING;\n        this.flagType = flagType;\n    }\n\n    public Flag(String name, byte[] bytesValue, int flagType) {\n        this.name = name;\n        this.bytesValue = bytesValue;\n        this.dataType = DATA_TYPE_BYTES;\n        this.flagType = flagType;\n    }\n\n    public long getLong() {\n        if (dataType == DATA_TYPE_LONG)\n            return longValue;\n        throw new IllegalArgumentException(\"Not a long type\");\n    }\n\n    public boolean getBool() {\n        if (dataType == DATA_TYPE_BOOL)\n            return boolValue;\n        throw new IllegalArgumentException(\"Not a boolean type\");\n    }\n\n    public double getDouble() {\n        if (dataType == DATA_TYPE_DOUBLE)\n            return doubleValue;\n        throw new IllegalArgumentException(\"Not a double type\");\n    }\n\n    public String getString() {\n        if (dataType == DATA_TYPE_STRING)\n            return stringValue;\n        throw new IllegalArgumentException(\"Not a String type\");","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java#L53-L89","documentation":"Flag.getLong() throws IllegalArgumentException(\"Not a long type\") when the flag's dataType is not DATA_TYPE_LONG. The phenotype Flag class stores several differently-typed values (long, bool, double, string, bytes) and each typed getter validates the flag's type discriminator before returning the field. Calling a getter that does not match the flag's actual type is treated as a programming error and fails fast.","triggerScenarios":"Calling Flag.getLong() on a Flag whose dataType is DATA_TYPE_BOOL (2), DATA_TYPE_DOUBLE (3), DATA_TYPE_STRING (4), or DATA_TYPE_BYTES (5) instead of DATA_TYPE_LONG (1). Typically happens when iterating a heterogeneous list of Flags and blindly casting/calling getLong() on each.","commonSituations":"Iterating server-fetched phenotype flags without switching on flagType/dataType; a server experiment changed a flag's type from long to boolean; deserializing flags from a Bundle or proto where the type constant was set by another code path; copy-pasted getter calls across flag refactors.","solutions":["Check flag.getDataType() (or flagType) before calling the getter and route to the matching getBool/getDouble/getString/getBytes","Add a switch/case over the DATA_TYPE_* constants that handles LONG and skips or defaults for other types","If the flag should always be long, verify the server-side experiment configuration hasn't changed the flag's type","Wrap the call in try-catch (IllegalArgumentException) only at boundaries where flag provenance is untrusted"],"exampleFix":"// before\nlong value = flag.getLong();\n// after\nlong value = flag.getDataType() == Flag.DATA_TYPE_LONG ? flag.getLong() : 0L;","handlingStrategy":"type-guard","validationCode":"if (flag.getDataType() != Flag.DATA_TYPE_LONG) { throw new IllegalStateException(\"flag is not a long: \" + flag.getDataType()); }","typeGuard":"static boolean isLongFlag(Flag f) { return f != null && f.getDataType() == Flag.DATA_TYPE_LONG; }","tryCatchPattern":"try { long v = flag.getLong(); } catch (IllegalArgumentException e) { log.warn(\"Flag type mismatch\", e); v = DEFAULT_LONG; }","preventionTips":["Always switch on flag.getDataType() before accessing a typed getter","Do not assume a flag's type is stable across server-side experiment updates","Centralize flag decoding in one helper that dispatches per DATA_TYPE_* constant","Log the flag name and dataType when a getter is rejected"],"tags":["android","phenotype","type-mismatch","flags"],"backgroundTag":"type-mismatch","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}