Skip to content

[bug] runtimes.elixir exposes mix but not erl inside AWF sandbox #44103

Description

@alanpeabody

erlef/setup-beam successfully installs OTP/Elixir before the agent runs.
However, the generated AWF/Copilot shell setup does not preserve the setup-beam PATH.
Instead, it reconstructs PATH from RUNNER_TOOL_CACHE with a depth-limited find.
That exposes an Elixir/mix binary, but not a working erl executable.
As a result, mix commands fail because Elixir tries to exec erl and cannot find it.

The failure is not that setup-beam failed. setup-beam successfully installed and verified OTP/Elixir
under:

/home/runner/work/_temp/.setup-beam/otp/bin/erl
/home/runner/work/_temp/.setup-beam/elixir/bin/mix

The bug is that the AWF/Copilot sandbox path bootstrap does not preserve those activated setup-beam
paths.

Relevant source:

  • /private/tmp/gh-aw-src/pkg/workflow/nodejs.go:189: GetNpmBinPathSetup scans only $RUNNER_TOOL_CACHE

  • /private/tmp/gh-aw-src/pkg/workflow/copilot_engine_execution.go:397: Copilot prepends
    GetNpmBinPathSetup() inside AWF

  • /private/tmp/gh-aw-src/pkg/workflow/runtime_definitions.go:69: runtimes.elixir uses erlef/setup-beam

  • /private/tmp/gh-aw-src/pkg/workflow/runtime_step_generator.go:24: comments assume AWF preserves setup
    action paths via AWF_HOST_PATH

  • /private/tmp/gh-aw-src/pkg/workflow/runtime_setup_test.go:393: Elixir tests only assert setup-beam is
    emitted, not that erl is reachable

GetNpmBinPathSetup currently does this:

export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\n' ':')$PATH"

That is insufficient for setup-beam because setup-beam’s active install is copied to $RUNNER_TEMP/.setup-
beam/..., then core.addPath(/bin) is called. The canonical erl is at $INSTALL_DIR_FOR_OTP/bin/
erl, not necessarily inside $RUNNER_TOOL_CACHE.

Increasing find -maxdepth is probably not the right fix. The agent found erl.src / erts-* artifacts in /
opt/hostedtoolcache, but the working executable verified by setup-beam was $INSTALL_DIR_FOR_OTP/bin/erl.

Secondary Issues

runtimes.elixir models only:

Commands: []string{"elixir", "mix", "iex"}

It should probably also include erl, erlc, and escript. That is not the direct mix test failure, but it
makes runtime detection incomplete.

The tests are too shallow. Current coverage proves “setup-beam step is generated,” but not “AWF shell can
resolve mix and erl after setup-beam.”

Proposed Fix

Best targeted fix: extend the AWF runtime PATH bootstrap to include setup-beam’s documented install dirs.

Something like:

for GH_AW_BEAM_DIR in
"${INSTALL_DIR_FOR_OTP:-}"
"${INSTALL_DIR_FOR_ELIXIR:-}"
"${INSTALL_DIR_FOR_GLEAM:-}"
"${INSTALL_DIR_FOR_REBAR3:-}"
do
if [ -n "$GH_AW_BEAM_DIR" ] && [ -d "$GH_AW_BEAM_DIR/bin" ]; then
export PATH="$GH_AW_BEAM_DIR/bin:$PATH"
fi
done

This should live either in GetNpmBinPathSetup after the toolcache scan, or preferably in a renamed/
generalized helper such as GetAWFRuntimePathSetup.

Better architectural fix: capture the post-setup host PATH before sudo -E awf and restore it inside AWF.
That matches the comments about AWF_HOST_PATH, but it is broader and may need more compatibility testing.

Tests To Add

  1. Add a unit test for the path helper:

    • create fake $RUNNER_TOOL_CACHE
    • create fake $INSTALL_DIR_FOR_OTP/bin/erl
    • create fake $INSTALL_DIR_FOR_ELIXIR/bin/mix
    • run the helper in bash
    • assert command -v erl and command -v mix resolve to setup-beam dirs
  2. Add a compile test for an Elixir runtime workflow:

    • runtimes.elixir
    • tools.bash: ["mix:*"]
    • assert the generated AWF command includes setup-beam install-dir PATH handling
  3. Expand runtime_definitions.go Elixir commands:

    • elixir
    • mix
    • iex
    • erl
    • erlc
    • escript

Similar Issues Found

Metadata

Metadata

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions