{"record":{"id":"b0959c938b434ee0","repo":"gradle/gradle","slug":"cannot-convert-s-to-s","errorCode":null,"errorMessage":"Cannot convert '%s' to %s.","messagePattern":"Cannot convert '(.+?)' to (.+?)\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"platforms/core-configuration/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileResolver.java","lineNumber":96,"sourceCode":"    public String resolveForDisplay(Object path) {\n        return resolveAsRelativePath(path);\n    }\n\n    @Override\n    public File resolve(Object path, PathValidation validation) {\n        File maybeRelativeFile = unpackAndParseNotation(path, fileNotationParser, \"File\");\n        return resolveFile(maybeRelativeFile, validation);\n    }\n\n    @Override\n    public URI resolveUri(Object uri) {\n        return unpackAndParseNotation(uri, uriOrFileNotationParser, \"URI\");\n    }\n\n    private static <T> T unpackAndParseNotation(Object input, NotationParser<Object, T> parser, String hint) {\n        Object unpacked = DeferredUtil.unpack(input);\n        if (unpacked == null || \"\".equals(unpacked)) {\n            throw new IllegalArgumentException(String.format(\"Cannot convert '%s' to %s.\", input, hint));\n        }\n        return parser.parseNotation(unpacked);\n    }\n\n    protected abstract File doResolve(File path);\n\n    private File resolveFile(File maybeRelativeFile, PathValidation validation) {\n        File file = doResolve(maybeRelativeFile);\n        file = FileUtils.normalize(file);\n        validate(file, validation);\n        return file;\n    }\n\n    protected void validate(File file, PathValidation validation) {\n        switch (validation) {\n            case NONE:\n                break;\n            case EXISTS:","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/core-configuration/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileResolver.java#L78-L114","documentation":"ConfigurationPublications lazily creates the variants container guarded by beforeCollectionChanges: once the configuration has been observed (resolved or consumed during task-graph building), adding secondary artifact sets via outgoing.variants { } throws InvalidUserCodeException naming the configuration and the observation reason.","triggerScenarios":"configurations.myOutgoing.outgoing.variants { register('extra') { artifact(file) } } executed after the configuration was resolved or its file collection consumed (task graph built, incoming.files read).","commonSituations":"Plugins registering additional variants in afterEvaluate or reactively after something already resolved the configuration; ordering conflicts between publishing plugins and early-resolving plugins.","solutions":["Register all variants eagerly during plugin application, before anything can resolve the configuration","Eliminate early resolution/consumption of the outgoing configuration","If late registration seems required, add a new consumable configuration instead of a late variant"],"exampleFix":"// before\nafterEvaluate {\n    configurations.myLib.outgoing.variants { // configuration already observed\n        documentation { artifact(javadocJar) }\n    }\n}\n\n// after\nconfigurations.myLib.outgoing.variants { // during apply, before observation\n    documentation { artifact(javadocJar) }\n}","handlingStrategy":"validation","validationCode":"if (conf.state != Configuration.State.UNRESOLVED) {\n    throw new GradleException(\"${conf.name} was observed; register variants earlier\")\n}\nconf.outgoing.variants { register('docs') { artifact(javadocJar) } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register variants during plugin apply, never in afterEvaluate","Prevent early resolution of outgoing configurations","Use one consumable configuration per variant set to avoid late additions"],"tags":["gradle","variants","outgoing","observed-state"],"backgroundTag":"configuration-mutation-after-resolve","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}