{"record":{"id":"22dc84d75d077715","repo":"microg/GmsCore","slug":"position-already-set-using-position","errorCode":null,"errorMessage":"Position already set using position()","messagePattern":"Position already set using position\\(\\)","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"play-services-maps/src/main/java/com/google/android/gms/maps/model/GroundOverlayOptions.java","lineNumber":310,"sourceCode":"        this.location = location;\n        this.width = width;\n        return this;\n    }\n\n    /**\n     * Specifies the position for this ground overlay. When rendered, the image will be scaled to\n     * fit the bounds (i.e., its proportions will not necessarily be preserved).\n     *\n     * @param bounds a {@link LatLngBounds} in which to place the ground overlay\n     * @return this {@link GroundOverlayOptions} object with a new position set.\n     * @throws IllegalStateException if the position was already set using\n     *                               {@link #position(LatLng, float)} or\n     *                               {@link #position(LatLng, float, float)}\n     */\n    public GroundOverlayOptions positionFromBounds(LatLngBounds bounds)\n            throws IllegalStateException {\n        if (location != null)\n            throw new IllegalStateException(\"Position already set using position()\");\n        this.bounds = bounds;\n        return this;\n    }\n\n    /**\n     * Specifies the transparency of the ground overlay. The default transparency is {code 0}\n     * (opaque).\n     *\n     * @param transparency a float in the range {@code [0..1]} where {@code 0} means that the\n     *                     ground overlay is opaque and {code 1} means that the ground overlay is\n     *                     transparent\n     * @return this {@link GroundOverlayOptions} object with a new visibility setting.\n     * @throws IllegalArgumentException if the transparency is outside the range [0..1].\n     */\n    public GroundOverlayOptions transparency(float transparency) throws IllegalArgumentException {\n        if (transparency < 0 || transparency > 1)\n            throw new IllegalArgumentException(\"transparency must be in range [0..1]\");\n        this.transparency = transparency;","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-maps/src/main/java/com/google/android/gms/maps/model/GroundOverlayOptions.java#L292-L328","documentation":"GroundOverlayOptions.positionFromBounds(LatLngBounds) throws IllegalStateException when the position was already set via position(LatLng, float) or position(LatLng, float, float). Only one positioning strategy is allowed per overlay; the builder detects an existing anchor location and rejects the bounds-based positioning. Note the converse error, 205, is thrown by position() when bounds were set first.","triggerScenarios":"Calling positionFromBounds(...) after position(...) on the same GroundOverlayOptions instance, typically in fluent chains or shared builders configured by multiple code paths.","commonSituations":"Refactoring an overlay from explicit dimensions to bounds-fitting without removing the old position() call; a common options factory method where callers additionally set a position; retry/reconfiguration logic that re-applies positioning on an existing builder.","solutions":["Remove the earlier position(...) call when using positionFromBounds(...).","Construct a fresh GroundOverlayOptions for each overlay instead of reusing and reconfiguring one builder.","Structure the builder setup as exclusive branches (if bounds -> positionFromBounds else position)."],"exampleFix":"// before\nGroundOverlayOptions opts = new GroundOverlayOptions()\n    .position(center, 1000f)\n    .positionFromBounds(bounds); // IllegalStateException\n\n// after\nGroundOverlayOptions opts = new GroundOverlayOptions()\n    .positionFromBounds(bounds); // choose one strategy only","handlingStrategy":"validation","validationCode":"if (alreadyCalledPosition) { /* do not call positionFromBounds(...) */ }","typeGuard":"boolean isBoundsFree(GroundOverlayOptions o) { return !o.getPositionSet(); } // track it yourself with a flag","tryCatchPattern":"try {\n    options.positionFromBounds(bounds);\n} catch (IllegalStateException e) {\n    // already positioned via position(); keep that strategy\n}","preventionTips":["Remove legacy position() calls when switching to bounds-based fitting.","Do not reconfigure a used builder; construct a new one.","Wrap positioning in a single helper that applies exactly one strategy."],"tags":["maps","android","ground-overlay","builder","state"],"backgroundTag":"invalid-state-transition","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"}