{"record":{"id":"b8e7749a1e1aa7bc","repo":"apache/dubbo","slug":"setscopemodel-is-forbidden-for-serviceaddressurl","errorCode":null,"errorMessage":"setScopeModel is forbidden for ServiceAddressURL","messagePattern":"setScopeModel is forbidden for ServiceAddressURL","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java","lineNumber":220,"sourceCode":"\n    @Override\n    public int hashCode() {\n        return super.hashCode();\n    }\n\n    @Override\n    public ScopeModel getScopeModel() {\n        return consumerURL.getScopeModel();\n    }\n\n    @Override\n    public ServiceModel getServiceModel() {\n        return consumerURL.getServiceModel();\n    }\n\n    @Override\n    public URL setScopeModel(ScopeModel scopeModel) {\n        throw new UnsupportedOperationException(\"setScopeModel is forbidden for ServiceAddressURL\");\n    }\n\n    @Override\n    public URL setServiceModel(ServiceModel serviceModel) {\n        throw new UnsupportedOperationException(\"setServiceModel is forbidden for ServiceAddressURL\");\n    }\n\n    /**\n     * ignore consumer url compare.\n     * It's only meaningful for comparing two address urls related to the same consumerURL.\n     *\n     * @param obj\n     * @return\n     */\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj) {\n            return true;","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java#L202-L238","documentation":"UnsupportedOperationException thrown by ServiceAddressURL.setScopeModel() because ServiceAddressURL is a read-only composite URL that delegates getScopeModel() to its wrapped consumerURL. A ServiceAddressURL represents a provider address paired with a consumer's configuration — the scope model belongs to the consumer, not the address, so mutating it on the address URL is semantically meaningless and explicitly forbidden. Callers must set the scope model on the underlying consumerURL instead.","triggerScenarios":"Calling setScopeModel() on an instance of ServiceAddressURL (or its concrete subclass). This URL type is constructed internally by Dubbo's registry/cluster layer when resolving provider addresses. Application or framework code that generically calls setScopeModel() on any URL without checking the concrete type will hit this.","commonSituations":"Generic URL-processing code (filters, custom SPI extensions, interceptors) that calls setScopeModel() on a URL that happens to be a ServiceAddressURL; migration to Dubbo 3.x where ServiceAddressURL became stricter about mutability; code that previously set scope model on address URLs in older Dubbo versions.","solutions":["Do not call setScopeModel() on ServiceAddressURL — set it on the consumer URL (accessible via getConsumerURL()) or the originating URL instead.","Add a type check before calling setScopeModel(): if (url instanceof ServiceAddressURL) skip or redirect to the consumer URL.","Review custom SPI/filter code for generic URL mutation patterns and make them aware of ServiceAddressURL's immutability contract."],"exampleFix":"// before — generic mutation fails on ServiceAddressURL\nurl.setScopeModel(scopeModel); // throws if url is ServiceAddressURL\n\n// after — set on the appropriate URL\nif (url instanceof ServiceAddressURL) {\n    ((ServiceAddressURL) url).getConsumerURL().setScopeModel(scopeModel);\n} else {\n    url.setScopeModel(scopeModel);\n}","handlingStrategy":"type-guard","validationCode":"// Check URL type before calling setScopeModel\nif (url instanceof ServiceAddressURL) {\n    // scope model belongs to the consumer URL — set it there\n    ((ServiceAddressURL) url).getConsumerURL().setScopeModel(scopeModel);\n} else {\n    url.setScopeModel(scopeModel);\n}","typeGuard":"public static boolean isMutableScopeModel(URL url) {\n    return !(url instanceof ServiceAddressURL);\n}","tryCatchPattern":"try {\n    url.setScopeModel(scopeModel);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"forbidden for ServiceAddressURL\")) {\n        // redirect to consumer URL\n        if (url instanceof ServiceAddressURL) {\n            ((ServiceAddressURL) url).getConsumerURL().setScopeModel(scopeModel);\n        }\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check url instanceof ServiceAddressURL before calling setScopeModel() on generic URL references.","Set scope model on the originating consumer URL, not on address URLs.","Audit custom filters/SPI extensions for blanket URL mutation calls.","Understand Dubbo 3.x URL hierarchy: ServiceAddressURL is a read-only composite."],"tags":["url","immutability","scope-model","architecture","dubbo3"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}