Skip to content

inputs.* expressions in prompt body not resolved when called via workflow_call #25717

@benvillalobos

Description

@benvillalobos

🤖 AI Assisted bug report

Summary

When a gh-aw compiled workflow is invoked as a reusable workflow (workflow_call) instead of workflow_dispatch, ${{ inputs.* }} expressions in the .md prompt body are not resolved. The agent sees the literal text ${{ inputs.errors }} instead of the actual value.

Reproduction

  1. Create an agentic workflow (.md) with both workflow_call and workflow_dispatch triggers, and ${{ inputs.some_input }} in the prompt body
  2. Compile with gh aw compile
  3. Call it from another workflow using uses: + with: (reusable workflow pattern)
  4. The agent receives the literal ${{ inputs.some_input }} text — the value is never substituted

Dispatching the same workflow via workflow_dispatch works correctly.

Root Cause

In actions/setup/js/runtime_import.cjs, the evaluateExpression() function resolves expressions differently depending on their prefix:

  • needs.* and steps.* (line ~275): Converted to GH_AW_* env var names and looked up in process.env. This works because the compiler sets these env vars in the lock file's "Create prompt" step.
  • inputs.*: Does NOT get the env var lookup. Falls through to the GitHub context path (line ~306): inputs: context.payload?.inputs || {}. For workflow_dispatch, context.payload.inputs is populated by GitHub Actions. For workflow_call, it is not — the inputs are delivered differently.

The compiler already generates the correct env vars (e.g., GH_AW_INPUTS_ERRORS: ${{ inputs.errors }}), and GitHub Actions resolves them in YAML for both trigger types. The values are available in process.env — the runtime just never reads them for inputs.* expressions.

Suggested Fix

Add inputs.* to the env var lookup condition at line ~275 of runtime_import.cjs:

// Before:
if (trimmed.startsWith("needs.") || trimmed.startsWith("steps.")) {

// After:
if (trimmed.startsWith("needs.") || trimmed.startsWith("steps.") || trimmed.startsWith("inputs.")) {

This makes inputs.errors resolve to process.env.GH_AW_INPUTS_ERRORS — the same pattern that already works for needs.* and steps.*.

Why It Was Not Caught

The existing workflow_call smoke test (smoke-workflow-call.md) declares no inputs and uses no ${{ inputs.* }} expressions in its prompt body, so this code path was never exercised.

Context

We discovered this while converting the a workflow from workflow_dispatch (fire-and-forget) to workflow_call (reusable workflow) so two workflows would appear as nodes in a single GitHub Actions run graph.

Metadata

Metadata

Type

No type
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