gradle/gradle · error · IllegalArgumentException

Cannot convert '%s' to %s.

Error message

Cannot convert '%s' to %s.

What it means

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.

Source

Thrown at platforms/core-configuration/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileResolver.java:96

    public String resolveForDisplay(Object path) {
        return resolveAsRelativePath(path);
    }

    @Override
    public File resolve(Object path, PathValidation validation) {
        File maybeRelativeFile = unpackAndParseNotation(path, fileNotationParser, "File");
        return resolveFile(maybeRelativeFile, validation);
    }

    @Override
    public URI resolveUri(Object uri) {
        return unpackAndParseNotation(uri, uriOrFileNotationParser, "URI");
    }

    private static <T> T unpackAndParseNotation(Object input, NotationParser<Object, T> parser, String hint) {
        Object unpacked = DeferredUtil.unpack(input);
        if (unpacked == null || "".equals(unpacked)) {
            throw new IllegalArgumentException(String.format("Cannot convert '%s' to %s.", input, hint));
        }
        return parser.parseNotation(unpacked);
    }

    protected abstract File doResolve(File path);

    private File resolveFile(File maybeRelativeFile, PathValidation validation) {
        File file = doResolve(maybeRelativeFile);
        file = FileUtils.normalize(file);
        validate(file, validation);
        return file;
    }

    protected void validate(File file, PathValidation validation) {
        switch (validation) {
            case NONE:
                break;
            case EXISTS:

View on GitHub (pinned to 534f27719b)

Solutions

  1. Register all variants eagerly during plugin application, before anything can resolve the configuration
  2. Eliminate early resolution/consumption of the outgoing configuration
  3. If late registration seems required, add a new consumable configuration instead of a late variant

Example fix

// before
afterEvaluate {
    configurations.myLib.outgoing.variants { // configuration already observed
        documentation { artifact(javadocJar) }
    }
}

// after
configurations.myLib.outgoing.variants { // during apply, before observation
    documentation { artifact(javadocJar) }
}
Defensive patterns

Strategy: validation

Validate before calling

if (conf.state != Configuration.State.UNRESOLVED) {
    throw new GradleException("${conf.name} was observed; register variants earlier")
}
conf.outgoing.variants { register('docs') { artifact(javadocJar) } }

Prevention

When it happens

Trigger: 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).

Common situations: Plugins registering additional variants in afterEvaluate or reactively after something already resolved the configuration; ordering conflicts between publishing plugins and early-resolving plugins.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/b0959c938b434ee0. Report an issue: GitHub.