gradle/gradle · error · InvalidIvyPublicationException
artifact file is a directory: '%s'
Error message
artifact file is a directory: '%s'
What it means
Gradle's Ivy publishing pipeline validates every artifact immediately before upload. ValidatingIvyPublisher.checkCanPublish rejects any artifact whose File is a directory, because an Ivy repository coordinate must point to a downloadable regular file.
Source
Thrown at platforms/software/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publisher/ValidatingIvyPublisher.java:145
"multiple artifacts with the identical name, extension, type and classifier ('%s', %s', '%s', '%s').",
name, extension, type, classifier
);
throw new InvalidIvyPublicationException(publication.getName(), message);
}
}
}
private boolean hasCoordinates(IvyArtifact one, String name, String extension, String type, String classifier) {
return Objects.equals(one.getName(), name)
&& Objects.equals(one.getType(), type)
&& Objects.equals(one.getExtension(), extension)
&& Objects.equals(one.getClassifier(), classifier);
}
private void checkCanPublish(String name, IvyArtifact artifact) {
File artifactFile = artifact.getFile();
if (artifactFile.isDirectory()) {
throw new InvalidIvyPublicationException(name, String.format("artifact file is a directory: '%s'", artifactFile));
}
}
private IvyFieldValidator field(IvyNormalizedPublication publication, String name, String value) {
return new IvyFieldValidator(publication.getName(), name, value);
}
private static class IvyFieldValidator extends PublicationFieldValidator<IvyFieldValidator> {
private IvyFieldValidator(String publicationName, String name, String value) {
super(IvyFieldValidator.class, publicationName, name, value);
}
public IvyFieldValidator matches(String expectedValue) {
if (!value.equals(expectedValue)) {
throw new InvalidIvyPublicationException(publicationName,
String.format("supplied %s does not match ivy descriptor (cannot edit %1$s directly in the ivy descriptor file).", name)
);
}View on GitHub (pinned to 534f27719b)
Solutions
- Attach a file-producing task or its output instead of a directory: publication.artifact(tasks.jar)
- If the content is a directory, package it first with a Zip/Jar task and publish that archive
- Add a doFirst guard on the publish task that fails fast when any artifact file is a directory
Example fix
// before
publication.artifact(file("$buildDir/resources/main")) // a directory
// after
publication.artifact(tasks.jar) // regular file produced by the build Defensive patterns
Strategy: validation
Validate before calling
tasks.withType(PublishToIvyRepository).configureEach {
doFirst {
publication.artifacts.each { a ->
if (a.file != null && a.file.isDirectory()) {
throw new GradleException("Ivy artifact '${a.file}' is a directory - attach a file (e.g. tasks.jar) instead")
}
}
}
} Try / catch
try {
project.tasks.named('publish').get().publish()
} catch (org.gradle.api.publish.ivy.InvalidIvyPublicationException e) {
// message names the offending directory; fix the artifact definition, do not retry blindly
} Prevention
- Always attach Ivy artifacts via task outputs (tasks.jar, custom Zip tasks) rather than raw File instances
- For directory content, define an archive task and publish its output
- Run a publishToMavenLocal-equivalent smoke publish in CI to catch artifact wiring errors before release
When it happens
Trigger: An IvyPublication artifact whose file resolves to a directory: publication.artifact(someDir), IvyArtifact.setFile(dir), or attaching a task whose output is a directory (Copy/Sync destinationDir, sourceSets.main.output) instead of an archive output like the Jar task's archiveFile.
Common situations: Pointing the artifact at the resources or classes directory instead of the packaged jar; build logic migrated from the old artifacts{...} syntax where builtBy pointed at a directory-producing task; scripts that publish a folder of native libs directly.
Related errors
- artifact file does not exist: '%s'
- Artifact %s wasn't produced by this build.
- multiple artifacts with the identical name, extension, type
- artifact file is a directory: '%s'
- impossible to publish {} using {}: no artifact pattern defin
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/60263c6e3391d51e.
Report an issue: GitHub.