Skip to content

Explain how to fix reusable workflow errors - #384

Open
dannymidnight wants to merge 1 commit into
mainfrom
pb/reusable-workflow-diagnostics
Open

Explain how to fix reusable workflow errors#384
dannymidnight wants to merge 1 commit into
mainfrom
pb/reusable-workflow-diagnostics

Conversation

@dannymidnight

@dannymidnight dannymidnight commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Why

A reusable workflow input such as:

with:
  target: prefix-${{ needs.prepare.outputs.target }}

currently suggests a needs output reference without saying that it must be the whole value of a string input. Remote secret forwarding, unreadable public workflows, and expression-valued uses similarly state constraints without naming the affected workflow or showing a supported alternative.

What

Make these reusable-workflow errors explain the next valid step:

  • Show the exact whole-value needs form and retain the distinct missing-needs and pre-job-value guidance.
  • Name remote workflows, state that no secrets were forwarded, and suggest job-level secret references or equivalent local calls. Local secrets: inherit and explicit maps remain supported.
  • Give the same non-enumerating private-or-absent guidance for an unavailable repository or missing public workflow path.
  • Replace “runtime-dependent” with literal local and public uses examples.

Closes PB-3041
Closes PB-3026
Closes PB-3016
Closes PB-3017

Preview

Needs expression input

Workflow could not be run

.github/workflows/caller.yml

Reusable workflow input "target" uses a needs expression in an unsupported form.

.github/workflows/caller.yml:14:15 · Job call

Pass the whole value as exactly ${{ needs.<job>.outputs.<name> }}, with nothing around it.

Only string inputs can take a needs value, and Buildkite resolves it before the called job runs, so the reference has to be the entire value rather than part of a larger expression.

If you need a computed input from job outputs, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.

Diagnostic detail

Reusable-workflow input "target" is not statically resolvable: unsupported compile-time context "needs"


Remote secrets: inherit

Workflow could not be run

.github/workflows/caller.yml

secrets: inherit cannot forward secrets to a workflow in another repository.

.github/workflows/caller.yml:4:11 · Job call

Reusable workflow "owner/workflows/.github/workflows/ci.yml@v1" is outside this repository, so no secrets were forwarded.

Reference each secret by name in the jobs of that workflow, or copy the workflow into this repository's .github/workflows and use secrets: inherit with a ./ call.

If you need secrets: inherit across repositories, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.


Remote secrets: map

Workflow could not be run

.github/workflows/caller.yml

A secrets: map cannot forward secrets to a workflow in another repository.

.github/workflows/caller.yml:4:11 · Job call

Reusable workflow "owner/workflows/.github/workflows/ci.yml@v1" is outside this repository, so no secrets were forwarded.

Reference each secret by name in the jobs of that workflow, or copy the workflow into this repository's .github/workflows and use a secrets: map with a ./ call.

If you need explicit secret mappings across repositories, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.


Unavailable public workflow

Workflow could not be run

.github/workflows/private.yml

Reusable workflow could not be read.

.github/workflows/private.yml:4:11 · Job call

"owner/private/.github/workflows/ci.yml@v1" is either private or does not exist.

Only public workflows can be called across repositories.

Check the path, or copy the workflow into this repository's .github/workflows and call it with a ./ path.

If you need private cross-repository calls, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.


Expression-valued workflow path

Workflow could not be run

.github/workflows/dynamic.yml

Reusable workflow path cannot be an expression.

.github/workflows/dynamic.yml:4:11 · Job call

"${{ inputs.workflow }}" is only known once the build is running, and the workflow file has to be read before that.

Name the file directly, for example ./.github/workflows/ci.yml, or org/shared/.github/workflows/ci.yml@v1.

If you need a computed workflow path, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.

@dannymidnight
dannymidnight marked this pull request as ready for review August 24, 2026 23:53

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remote-secret diagnostics include an unsupported remediation; the inline comment points to the existing authority path.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 20461, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

About buildsworth

Model: gpt-5.6-sol with xhigh thinking.

How to request a review: Comment @buildsworth-bk review on the PR, or request buildsworth-bk as a reviewer.

Risk labels (how buildsworth classifies risk) — buildsworth classifies risk itself from the diff. Unless repository policy already allows L2 approval, grant it by mentioning @buildsworth-bk (see approval ceiling and L2 approval grant):

  • L1 — Low risk (dep bumps, docs/copy, lockfiles, small presentational fixes). buildsworth may approve by default.
  • L2 — Standard risk (new UI, additive API fields, refactors). Approved only when repository policy or a verified grant allows it; otherwise comment-only.
  • L3 — High risk (auth, migrations, payments, secrets, perf-critical paths). Human review always required.

}
if (call.InheritSecrets || len(call.Secrets) != 0) && calleeSource.identity.kind != "workspace" {
return reusableResolution{}, locatedJobError(path, job, call.Span.Start.Line, call.Span.Start.Column, "secret forwarding is supported only for repository-local reusable workflows")
message := fmt.Sprintf("A secrets: map cannot forward secrets to a workflow in another repository. Reusable workflow %q is outside this repository, so no secrets were forwarded. Reference each secret by name in the jobs of that workflow, or copy the workflow into this repository's .github/workflows and use a secrets: map with a ./ call. If you need explicit secret mappings across repositories, log an issue on github.com/buildkite/buildkite-gha so we can prioritise it.", calleeSource.displayPath)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: The first remediation in both messages still leaves the remote jobs without secret authority. Calls with no forwarding produce an empty restricted binding set in resolveCallSecretAuthority, so requiredSecrets drops direct ${{ secrets.NAME }} references—the existing TestCompileDoesNotGrantUninheritedReusableWorkflowSecrets covers this behavior. A user following this guidance receives an empty value at runtime. Please remove that option, or name buildkite-agent secret get NAME explicitly if that is the intended job-level mechanism.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants