{"record":{"id":"ba79bc6815c7d354","repo":"gradle/gradle","slug":"unable-to-find-matching-strategy-for","errorCode":null,"errorMessage":"Unable to find matching strategy for {}","messagePattern":"Unable to find matching strategy for (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"platforms/software/dependency-management/src/main/java/org/gradle/api/internal/attributes/DefaultAttributesSchema.java","lineNumber":55,"sourceCode":"    private final IsolatableFactory isolatableFactory;\n\n    private final Map<Attribute<?>, DefaultAttributeMatchingStrategy<?>> strategies = new HashMap<>();\n    private final Set<Attribute<?>> precedence = new LinkedHashSet<>();\n\n    @Inject\n    public DefaultAttributesSchema(InstantiatorFactory instantiatorFactory, IsolatableFactory isolatableFactory) {\n        this.instantiatorFactory = instantiatorFactory;\n        this.isolatableFactory = isolatableFactory;\n    }\n\n    // region public API\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public <T> AttributeMatchingStrategy<T> getMatchingStrategy(Attribute<T> attribute) {\n        AttributeMatchingStrategy<T> strategy = (DefaultAttributeMatchingStrategy<T>) strategies.get(attribute);\n        if (strategy == null) {\n            throw new IllegalArgumentException(\"Unable to find matching strategy for \" + attribute);\n        }\n        return strategy;\n    }\n\n    @Override\n    public <T> AttributeMatchingStrategy<T> attribute(Attribute<T> attribute) {\n        return attribute(attribute, null);\n    }\n\n    @Override\n    public <T> AttributeMatchingStrategy<T> attribute(Attribute<T> attribute, @Nullable Action<? super AttributeMatchingStrategy<T>> configureAction) {\n        AttributeMatchingStrategy<T> strategy = getStrategy(attribute);\n        if (configureAction != null) {\n            configureAction.execute(strategy);\n        }\n        return strategy;\n    }\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/software/dependency-management/src/main/java/org/gradle/api/internal/attributes/DefaultAttributesSchema.java#L37-L73","documentation":"An AttributesSchema maps each Attribute to a matching strategy holding its compatibility and disambiguation rules; DefaultAttributesSchema.getMatchingStrategy throws IllegalArgumentException when the attribute was never registered via attributesSchema { attribute(...) }. The same lookup runs inside variant selection, so selecting on an undeclared attribute surfaces this error from deep within dependency resolution or any direct getMatchingStrategy call.","triggerScenarios":"Calling dependencies.attributesSchema.getMatchingStrategy(MyAttribute) before declaring attributesSchema.attribute(MyAttribute); a plugin setting configuration/consumer attributes (attributes { attribute(CUSTOM, ...) }) in a project whose schema never registered that attribute; an attribute with a slightly different name or type than the registered instance so the map lookup misses.","commonSituations":"Convention applied to the root project but the attribute used in subprojects (schemas are per-project); plugin sets attributes without registering the schema entry; Attribute.of('custom.name', String) vs Attribute.of('custom.Name', String) mismatches after refactor.","solutions":["Declare the attribute before any use: dependencies.attributesSchema { attribute(MyAttribute) } in every project that selects on it (or via a convention plugin applied to all)","Plugin authors: register the attribute in the schema when the plugin is applied","Ensure name AND type of the Attribute instance match exactly between declaration and usage sites"],"exampleFix":"// before\ndef OPT = Attribute.of('pkg.optimization', String)\nconfigurations.runtimeClasspath { attributes { attribute(OPT, 'size') } } // never declared -> error\n\n// after\ndef OPT = Attribute.of('pkg.optimization', String)\ndependencies.attributesSchema { attribute(OPT) }\nconfigurations.runtimeClasspath { attributes { attribute(OPT, 'size') } }","handlingStrategy":"validation","validationCode":"// guard any strategy lookup / attribute use with a schema registration check\ndef schema = project.dependencies.attributesSchema\nif (!schema.hasAttribute(MyAttribute)) {\n    schema.attribute(MyAttribute)   // or throw, if the attribute must already be declared elsewhere\n}\ndef strategy = schema.getMatchingStrategy(MyAttribute)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In plugins, register custom attributes in attributesSchema at apply time","Apply attribute declarations via a convention plugin to every project that uses them","Create Attribute instances in exactly one place (static final) and reuse them everywhere"],"tags":["gradle","attributes","variant-matching","schema"],"backgroundTag":"undeclared-attribute-strategy","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}