{"record":{"id":"c5097162edc244b3","repo":"microg/GmsCore","slug":"geofence-must-be-created-using-geofence-builder","errorCode":null,"errorMessage":"Geofence must be created using Geofence.Builder.","messagePattern":"Geofence must be created using Geofence\\.Builder\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-location/src/main/java/com/google/android/gms/location/GeofencingRequest.java","lineNumber":105,"sourceCode":"    /**\n     * A builder that builds {@link GeofencingRequest}.\n     */\n    public static class Builder {\n        private List<Geofence> geofences = new ArrayList<>();\n        private @InitialTrigger int initialTrigger = INITIAL_TRIGGER_ENTER | INITIAL_TRIGGER_DWELL;\n\n        /**\n         * Adds a geofence to be monitored by geofencing service.\n         *\n         * @param geofence the geofence to be monitored. The geofence must be built with {@link Geofence.Builder}.\n         * @return the builder object itself for method chaining\n         * @throws IllegalArgumentException if the geofence is not built with {@link Geofence.Builder}.\n         * @throws NullPointerException     if the given geofence is null\n         */\n        @NonNull\n        public GeofencingRequest.Builder addGeofence(Geofence geofence) {\n            if (geofence == null) throw new NullPointerException(\"geofence can't be null.\");\n            if (!(geofence instanceof ParcelableGeofence)) throw new IllegalArgumentException(\"Geofence must be created using Geofence.Builder.\");\n            geofences.add(geofence);\n            return this;\n        }\n\n        /**\n         * Adds all the geofences in the given list to be monitored by geofencing service.\n         *\n         * @param geofences the geofences to be monitored. The geofences in the list must be built with {@link Geofence.Builder}.\n         * @return the builder object itself for method chaining\n         * @throws IllegalArgumentException if the geofence is not built with {@link Geofence.Builder}.\n         */\n        @NonNull\n        public GeofencingRequest.Builder addGeofences(List<Geofence> geofences) {\n            if (geofences != null) {\n                for (Geofence geofence : geofences) {\n                    if (geofence != null) addGeofence(geofence);\n                }\n            }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-location/src/main/java/com/google/android/gms/location/GeofencingRequest.java#L87-L123","documentation":"addGeofence() only accepts instances of ParcelableGeofence, the internal type produced by Geofence.Builder.build(). Passing any other Geofence implementation (e.g. a mock, a subclass, or a foreign implementation) cannot be marshaled into the request, so IllegalArgumentException is thrown.","triggerScenarios":"Calling addGeofence(geofence) where geofence is not an instanceof ParcelableGeofence — e.g. created via Mockito, a custom Geofence implementation, or deserialized from another source.","commonSituations":"Unit tests passing mocked Geofences into a real builder; custom Geofence implementations from wrapper libraries; reflection-based construction bypassing Geofence.Builder.","solutions":["Always create geofences via Geofence.Builder().build() before adding them to the request","In tests, use the real Geofence.Builder to construct fixtures instead of mocks","Avoid custom Geofence implementations; the public API expects builder-produced instances"],"exampleFix":"// before\nGeofence mockFence = Mockito.mock(Geofence.class);\nrequestBuilder.addGeofence(mockFence); // throws\n// after\nGeofence fence = new Geofence.Builder()\n    .setRequestId(\"fence1\")\n    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)\n    .setCircularRegion(lat, lng, 100f)\n    .setExpirationDuration(3600000)\n    .build();\nrequestBuilder.addGeofence(fence);","handlingStrategy":"validation","validationCode":"if (!(geofence instanceof ParcelableGeofence)) {\n    throw new IllegalStateException(\"Geofence must come from Geofence.Builder.build()\");\n}\nrequestBuilder.addGeofence(geofence);","typeGuard":"static boolean isBuilderCreated(Geofence g) { return g instanceof ParcelableGeofence; }","tryCatchPattern":"try { builder.addGeofence(fence); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Geofence.Builder\")) { throw new IllegalStateException(\"Recreate fence with Geofence.Builder\", e); } throw e; }","preventionTips":["Never mock Geofence in tests that feed real GeofencingRequest builders — build real fixtures","Avoid custom Geofence implementations; use only Geofence.Builder output"],"tags":["geofencing","type-mismatch","android","validation"],"backgroundTag":"invalid-argument-value","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"}