{"record":{"id":"2f85b82231194dd1","repo":"microg/GmsCore","slug":"element-in-keys-cannot-be-null-or-empty","errorCode":null,"errorMessage":"Element in keys cannot be null or empty","messagePattern":"Element in keys cannot be null or empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-auth-blockstore/src/main/java/com/google/android/gms/auth/blockstore/DeleteBytesRequest.java","lineNumber":47,"sourceCode":"@SafeParcelable.Class\npublic class DeleteBytesRequest extends AbstractSafeParcelable {\n\n    @Field(value = 1, getterName = \"getKeys\")\n    private final List<String> keys;\n\n    @Field(value = 2, getterName = \"getDeleteAll\")\n    private final boolean deleteAll;\n\n    @Constructor\n    DeleteBytesRequest(@Param(1) List<String> keys, @Param(2) boolean deleteAll) {\n        this.keys = keys;\n        this.deleteAll = deleteAll;\n        if (deleteAll && keys != null && !keys.isEmpty()) {\n            throw new IllegalArgumentException(\"deleteAll was set to true but keys were also provided\");\n        }\n        for (String key : keys) {\n            if (key == null || key.isEmpty()) {\n                throw new IllegalArgumentException(\"Element in keys cannot be null or empty\");\n            }\n        }\n    }\n\n    /**\n     * Returns the list of keys whose associated data, if any, should be deleted.\n     * <p>\n     * An empty list means that no key-based filtering will be performed. In other words, no data will be deleted if the key list is empty and no other\n     * criterion is provided.\n     * <p>\n     * Note that the app data that was stored without an explicit key can be deleted with the default key\n     * {@link BlockstoreClient#DEFAULT_BYTES_DATA_KEY}.\n     */\n    @NonNull\n    public List<String> getKeys() {\n        return keys;\n    }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-auth-blockstore/src/main/java/com/google/android/gms/auth/blockstore/DeleteBytesRequest.java#L29-L65","documentation":"DeleteBytesRequest validates every entry of the keys list: any null or empty-string element is rejected with IllegalArgumentException. The keys parameter cannot be null here because the deleteAll check above guarantees keys is non-null when iterating.","triggerScenarios":"Constructing DeleteBytesRequest (directly or via builder) with a keys list that contains a null element or a \"\" (empty string) element.","commonSituations":"Populating keys from dynamic sources such as user input, a database cursor, or a collection that may contain nulls/empty strings without filtering them out first.","solutions":["Filter the list before constructing: remove null and empty strings from the keys collection.","If a null/empty entry means 'no key', skip it instead of adding it to the list.","If the resulting list is empty after filtering, decide whether the request is still meaningful before calling the API."],"exampleFix":"// before\nList<String> keys = rawKeys; // may contain nulls/\"\"\nDeleteBytesRequest req = new DeleteBytesRequest(keys, false);\n// after\nList<String> keys = rawKeys.stream().filter(k -> k != null && !k.isEmpty()).collect(Collectors.toList());\nDeleteBytesRequest req = new DeleteBytesRequest(keys, false);","handlingStrategy":"validation","validationCode":"List<String> clean = keys == null ? Collections.emptyList() : keys.stream().filter(k -> k != null && !k.isEmpty()).collect(Collectors.toList());\nif (clean.isEmpty()) return; // nothing to delete","typeGuard":"boolean isValidKey(String k) { return k != null && !k.isEmpty(); }","tryCatchPattern":"try { request = new DeleteBytesRequest(keys, false); } catch (IllegalArgumentException e) { log.warn(\"Bad keys list\", e); }","preventionTips":["Sanitize any keys list built from dynamic/external sources.","Use Collections.singletonList for single-key deletes to avoid null entries.","Unit-test key-list assembly code with null/empty entries."],"tags":["android","blockstore","validation","illegal-argument"],"backgroundTag":"empty-required-field","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"}