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

  1. Ensure the target parent directory exists (Files.createDirectories(output.getParent()) before copy)
  2. Check filesystem write permissions for the build output location
  3. Verify the archive layout still places resources.txt three levels deep; adjust getParent() traversal if layout changed
  4. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7945175ccb57ab07. Report an issue: GitHub.