{"record":{"id":"604d783d812bc1b2","repo":"microg/GmsCore","slug":"invalid-license-meta-data-line","errorCode":null,"errorMessage":"Invalid license meta-data line:\n","messagePattern":"Invalid license meta-data line:\n","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"play-services-oss-licenses/src/main/java/org/microg/gms/oss/licenses/LicenseUtil.java","lineNumber":48,"sourceCode":"        try (InputStream is = resources.openRawResource(resources.getIdentifier(\"third_party_licenses\", \"raw\", context.getPackageName()))) {\n            if (is == null || is.available() <= 0) return false;\n        } catch (IOException e) {\n            return false;\n        }\n        return true;\n    }\n\n    public static List<License> getLicensesFromMetadata(Context context) {\n        Resources resources = context.getApplicationContext().getResources();\n        InputStream is = resources.openRawResource(resources.getIdentifier(\"third_party_license_metadata\", \"raw\", context.getPackageName()));\n        String metadata = readStringAndClose(is, Integer.MAX_VALUE);\n        String[] lines = metadata.split(\"\\n\");\n        List<License> licenses = new ArrayList<>(lines.length);\n        for (String line : lines) {\n            int spaceIndex = line.indexOf(' ');\n            String[] position = line.substring(0, spaceIndex).split(\":\");\n            if (spaceIndex <= 0 || position.length != 2) {\n                throw new IllegalStateException(\"Invalid license meta-data line:\\n\" + line);\n            }\n            licenses.add(new License(line.substring(spaceIndex + 1), Long.parseLong(position[0]), Integer.parseInt(position[1]), \"\"));\n        }\n        return licenses;\n    }\n\n    public static String getLicenseText(Context context, License license) {\n        if (license.getPath().isEmpty()) {\n            Resources resources = context.getApplicationContext().getResources();\n            InputStream is = resources.openRawResource(resources.getIdentifier(\"third_party_licenses\", \"raw\", context.getPackageName()));\n            try {\n                if (is.skip(license.getOffset()) != license.getOffset()) {\n                    throw new RuntimeException(\"Failed to read license\");\n                }\n            } catch (IOException e) {\n                throw new RuntimeException(\"Failed to read license\", e);\n            }\n            return readStringAndClose(is, license.getLength());","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-oss-licenses/src/main/java/org/microg/gms/oss/licenses/LicenseUtil.java#L30-L66","documentation":"LicenseUtil.getLicensesFromMetadata parses a newline-delimited metadata string where each line is '<offset>:<length> <title>'. If a line has no space before the first position char or the position part does not split into exactly two ':'-separated values, the metadata is malformed and the method throws IllegalStateException with the offending line.","triggerScenarios":"Calling getLicensesFromMetadata with a metadata string whose line lacks a space, or whose leading token is not 'long:int' (e.g. wrong line order, empty trailing segment, or a tool generated the metadata in a different format).","commonSituations":"Custom OSS-license gradle plugins or manual packaging produce metadata that differs from microG's expected format; strings files edited by hand; license metadata generated by a different (Google Play) tool version.","solutions":["Regenerate third_party_licenses metadata with a tool that emits '<offset>:<length> <title>' lines","Inspect the offending line printed in the exception and fix its format (add the space, make the position 'long:int')","Check for stray newline/empty lines or splitting bugs in the code that assembles the metadata string"],"exampleFix":"// before\nString line = \"licenses.html MIT License\"; // position not long:int\n// after\nString line = \"0:1523 MIT License\"; // <offset>:<length> <title>","handlingStrategy":"try-catch","validationCode":"// Validate each metadata line before parsing\nfor (String line : metadata.split(\"\\n\")) {\n    int spaceIndex = line.indexOf(' ');\n    if (spaceIndex <= 0) continue;\n    String[] pos = line.substring(0, spaceIndex).split(\":\");\n    if (pos.length != 2 || !pos[0].matches(\"\\\\d+\") || !pos[1].matches(\"\\\\d+\")) {\n        Log.w(TAG, \"Skipping malformed metadata line: \" + line);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    List<License> licenses = LicenseUtil.getLicensesFromMetadata(context);\n} catch (IllegalStateException e) {\n    Log.e(TAG, \"Malformed license metadata: \" + e.getMessage());\n    licenses = Collections.emptyList();\n}","preventionTips":["Generate metadata with the matching microG license tool format '<offset>:<length> <title>'","Trim stray whitespace/empty lines from the metadata string before parsing","Pin the license-metadata generator version so format changes surface in CI"],"tags":["java","parsing","oss-licenses"],"backgroundTag":"invalid-argument-format","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}