quarkusio/quarkus · error · IllegalStateException
Failed to copy " + p + " to " + output
Error message
Failed to copy " + p + " to " + output
What it means
This IllegalStateException wraps an IOException thrown when Files.copy fails while copying the located resources.txt to a launch-mode-prefixed output path derived from the file's location (three parent directories up). The build step copies the resource out of the app archive so the test can assert it was packaged; the copy failing means an I/O problem writing the target path.
Source
Thrown at integration-tests/gradle/src/main/resources/test-resources-in-build-steps/deployment/src/main/java/org/acme/ext/deployment/AcmeExtProcessor.java:29
import java.nio.file.StandardCopyOption;
class AcmeExtProcessor {
private static final String FEATURE = "acme-ext";
@BuildStep
FeatureBuildItem feature(ApplicationArchivesBuildItem appArchivesBuildItem,
LaunchModeBuildItem launchModeBuildItem) {
Path p = appArchivesBuildItem.getRootArchive().getChildPath("resources.txt");
if(p == null) {
throw new IllegalStateException("Failed to locate resources.txt in the project's resources");
}
final Path output = p.getParent().getParent().getParent().resolve(launchModeBuildItem.getLaunchMode() + "-" + p.getFileName());
try {
Files.copy(p, output, StandardCopyOption.REPLACE_EXISTING);
} catch(IOException e) {
throw new IllegalStateException("Failed to copy " + p + " to " + output, e);
}
return new FeatureBuildItem(FEATURE);
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the target parent directory exists (Files.createDirectories(output.getParent()) before copy)
- Check filesystem write permissions for the build output location
- Verify the archive layout still places resources.txt three levels deep; adjust getParent() traversal if layout changed
- Run a clean build to remove stale/partial output
Example fix
// before Files.copy(p, output, StandardCopyOption.REPLACE_EXISTING); // after Files.createDirectories(output.getParent()); Files.copy(p, output, StandardCopyOption.REPLACE_EXISTING);
Defensive patterns
Strategy: validation
Validate before calling
Path parent = output.getParent();
if (!Files.isDirectory(parent)) {
Files.createDirectories(parent);
}
if (!Files.isWritable(parent)) {
throw new IllegalStateException("Output dir not writable: " + parent);
} Try / catch
try {
Files.copy(p, output, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IllegalStateException("Failed to copy " + p + " to " + output, e);
} Prevention
- Always createDirectories for derived output paths
- Verify parent traversal (getParent().getParent().getParent()) against the actual archive layout
- Check CI workspace permissions
When it happens
Trigger: The output directory (p.getParent().getParent().getParent().resolve(<launchMode>-resources.txt)) does not exist, is not writable, or the source path becomes unreadable during the build step feature() execution.
Common situations: Target parent directory not created beforehand; permissions issue in CI workspace; read-only build output; unexpected archive layout changing parent traversal so output points into a nonexistent directory.
Related errors
- Failed to locate resources.txt in the project's resources
- %s is marked @Record but does not inject an @Recorder object
- Cannot write service provider file '${resourceName}': this G
- One of either visitorFunction or inputTransformer must be se
- Failed to copy %s to %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/7945175ccb57ab07.
Report an issue: GitHub.