Summary
PR #24501 fixed repo-root-relative path resolution in the compile-time ResolveIncludePath (pkg/parser/remote_fetch.go), but the runtime import resolver (actions/setup/js/runtime_import.cjs) was not updated to match. Paths like /.agents/skills/my-skill/instructions.md resolve correctly at compile time but fail at runtime with:
ERR_API: Failed to process runtime import for /.agents/skills/my-skill/instructions.md:
ERR_SYSTEM: Runtime import file not found: /home/runner/work/<repo>/<repo>/.github/workflows/.agents/skills/my-skill/instructions.md
The runtime handler prepends .github/workflows/ to the path instead of resolving from the repo root.
Root Cause
In actions/setup/js/runtime_import.cjs, processRuntimeImport (line ~739) has three branches for path resolution:
- Starts with
.agents/ → resolve from GITHUB_WORKSPACE (repo root)
- Starts with
.github/ → strip prefix, resolve under $WORKSPACE/.github
- Anything else → prepend
workflows/, resolve under $WORKSPACE/.github
A path like /.agents/skills/my-skill/instructions.md has a leading /, so it does NOT match startsWith(".agents/"). It falls into branch 3, producing .github/workflows/.agents/skills/my-skill/instructions.md.
The compile-time resolver (remote_fetch.go) handles this correctly by stripping the leading / before the prefix checks — but the runtime resolver never got the equivalent fix.
Reproduction
- Place agent skill files in
.agents/skills/ at the repo root
- In a workflow
.md file, use:
imports:
- /.agents/skills/my-skill/instructions.md
- Compile with
gh aw compile — succeeds, skill content is inlined
- The compiled
.lock.yml contains {{#runtime-import /.agents/skills/my-skill/instructions.md}}
- When the workflow runs on GitHub Actions, the runtime import fails with the error above
gh-aw version: v0.67.1
Proposed Fix
In actions/setup/js/runtime_import.cjs, add a leading-/ strip before the existing prefix checks (around line 749):
// Strip leading "/" for repo-root-absolute paths (e.g. /.agents/skills/..., /.github/agents/...).
// After stripping, the existing .agents/ and .github/ prefix checks handle resolution correctly.
if (filepath.startsWith("/")) {
const stripped = filepath.substring(1);
if (stripped.startsWith(".agents/") || stripped.startsWith(".agents\\") ||
stripped.startsWith(".github/") || stripped.startsWith(".github\\")) {
filepath = stripped;
}
}
This mirrors the behavior of ResolveIncludePath in pkg/parser/remote_fetch.go (lines 160-170) which was fixed in PR #24501. If the stripped path doesn't start with .agents/ or .github/, it falls through unchanged to the existing default branch — maintaining the same security restrictions.
Related
Summary
PR #24501 fixed repo-root-relative path resolution in the compile-time
ResolveIncludePath(pkg/parser/remote_fetch.go), but the runtime import resolver (actions/setup/js/runtime_import.cjs) was not updated to match. Paths like/.agents/skills/my-skill/instructions.mdresolve correctly at compile time but fail at runtime with:The runtime handler prepends
.github/workflows/to the path instead of resolving from the repo root.Root Cause
In
actions/setup/js/runtime_import.cjs,processRuntimeImport(line ~739) has three branches for path resolution:.agents/→ resolve fromGITHUB_WORKSPACE(repo root).github/→ strip prefix, resolve under$WORKSPACE/.githubworkflows/, resolve under$WORKSPACE/.githubA path like
/.agents/skills/my-skill/instructions.mdhas a leading/, so it does NOT matchstartsWith(".agents/"). It falls into branch 3, producing.github/workflows/.agents/skills/my-skill/instructions.md.The compile-time resolver (
remote_fetch.go) handles this correctly by stripping the leading/before the prefix checks — but the runtime resolver never got the equivalent fix.Reproduction
.agents/skills/at the repo root.mdfile, use:gh aw compile— succeeds, skill content is inlined.lock.ymlcontains{{#runtime-import /.agents/skills/my-skill/instructions.md}}gh-aw version: v0.67.1
Proposed Fix
In
actions/setup/js/runtime_import.cjs, add a leading-/strip before the existing prefix checks (around line 749):This mirrors the behavior of
ResolveIncludePathinpkg/parser/remote_fetch.go(lines 160-170) which was fixed in PR #24501. If the stripped path doesn't start with.agents/or.github/, it falls through unchanged to the existing default branch — maintaining the same security restrictions.Related
ResolveIncludePath#24501 — PR that fixed the compile-time resolver but not the runtime resolver