Skip to content

Java and .NET runtimes fail to execute inside AWF chroot mode (v0.13.14) #711

@Mossaka

Description

@Mossaka

Summary

Java and .NET runtimes are completely non-functional inside the AWF agent container in chroot mode. All 20 repos tested (10 Java, 10 .NET) failed with 0 successful builds and 0 tests run. This was discovered during a large-scale build/test experiment across 98 OSS repositories spanning 10 programming languages.

Environment

  • gh-aw: v0.43.2
  • AWF: v0.13.14
  • Runner: ubuntu-latest (GitHub Actions)
  • Chroot mode: enabled (--enable-chroot)

.NET Failure

All 10 .NET repos failed identically. The dotnet CLI refuses to execute because it detects a process name mismatch:

Error: cannot execute dotnet when renamed to bash.
exit code: 132

The .NET CLR validates that its hosting process name matches "dotnet". Inside the AWF chroot execution chain (chroot → bash → capsh → bash → exec), the process name resolves to "bash" instead of "dotnet", triggering this hard security check.

Repos tested: BenchmarkDotNet, Bogus, Dapper, FluentValidation, Humanizer, Newtonsoft.Json, Polly, moq4, serilog, xunit

The Copilot agent attempted multiple workarounds including direct execution, wrapper scripts, Python subprocess, C wrappers, symlinks, and setsid — none could bypass the .NET SDK's process name validation.

Java Failure

All 10 Java repos failed identically. The Java binary outputs bash version information instead of executing Java commands. Maven and Gradle builds fail because the JVM cannot properly initialize.

Repos tested: caffeine, gson, guava, jackson-databind, mapstruct, mockito, mybatis-3, okhttp, resilience4j, retrofit

The root cause appears to be the same /proc/self/exe resolution issue — the JVM reads /proc/self/exe and finds /bin/bash instead of the Java binary, causing it to behave as a shell rather than a JVM.

Context

This was part of a build/test experiment across 10 languages (98 repos total). For comparison:

  • Go: 8/10 repos built and tested successfully
  • Python: 8/10 repos built successfully
  • Rust: 3/10 fully passed (others hit separate linker/toolchain issues)
  • JavaScript: 9/10 pipelines green
  • Java: 0/10 — completely broken
  • .NET: 0/10 — completely broken

The procfs mounting fix introduced in v0.13.13 (container-scoped mount -t proc at /host/proc) does not resolve these failures in v0.13.14.

Reproduction

  1. Fork any Java or .NET repo (e.g., google/gson or dotnet/BenchmarkDotNet)
  2. Add an agentic workflow with engine: copilot and network.allowed: [defaults, java] or [defaults, dotnet]
  3. Compile with gh aw compile
  4. Trigger the workflow
  5. Observe the agent fails to execute java, mvn, gradle, or dotnet commands inside the AWF container

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions