Synthetic Industry

Troubleshooting guide · updated 2026-10-11

A CI secret exists but the job gets an empty value: check where the run may see it

Four reasons a secret you created is not visible to a job, how an unset secret fails later and elsewhere, a safe presence check, and what is yours to change.

Why an unset secret fails somewhere else

In GitHub Actions an unset secret does not raise an error: it evaluates to an empty string. The job carries on, sends an empty password or token, and fails later with an authentication message that points at the service, not at your workflow. That is why the symptom, for example a 401 from a registry, can send people to renew a secret that was never wrong. The first question is not whether the secret is correct but whether this run was allowed to see it.

Four scopes that hide a secret

Environment secrets belong to an environment and are available only to jobs that name that environment, and only after its protection rules, such as required reviewers, have passed. A secret stored on the environment is invisible to a job that does not reference it.

Reusable workflows do not inherit secrets. They are passed only to the workflow you call directly, either by name or, within the same organisation, with an inherit keyword, and in a chain each hop must pass them again. If the caller omits an environment secret, the called workflow sees an empty string; marking it required checks that it was passed, not that it has a value.

Dependabot-triggered runs read a separate store. A secret saved only as an Actions secret is not available to them, which is a common reason a dependency update fails while your own pull requests pass.

Runs triggered from a fork receive no secrets except the built-in token. That is deliberate, and the right design is a workflow that works without secrets for untrusted code, not a way to hand them over.

  • Environment secrets need the job to name the environment.
  • Reusable workflows need secrets passed explicitly.
  • Dependabot runs need Dependabot secrets.
  • Fork runs get none, by design.

A safe presence check

You do not need to print a secret to find out whether it arrived. Secrets cannot be tested directly in a condition, so the usual approach is to copy the secret into an environment variable for the job and test whether that variable is empty, printing only the words present or missing. Never print the value, never enable debug output to see it, and remember that values that are not stored as secrets must be masked by hand, and that encoding a value is not protection. Run the check on a branch for the same trigger that fails, and compare it with a run that succeeds, to see which of the four scopes differs.

What is yours, and what a repair can change

Creating, renewing or rotating a secret, adding it to the right store and deciding which environments and branches may use it are your decisions. A repair can change the workflow: name the environment on the job, pass the secret to the reusable workflow, split a workflow so that the untrusted part runs without secrets, or make an unset value fail early with a clear message instead of an authentication error later. A repair must not widen access to untrusted triggers to make a job pass.

How a paid repair is accepted

If the secret exists and the workflow simply does not pass it to the job, the existing one-job repair may fit, because the cause is workflow configuration. Its acceptance is the existing one: the named job passes on the same trigger on a branch, with before and after logs, and no unrelated workflow file changes. We would confirm the fit from a redacted log before any access, and we would not widen access for untrusted triggers to make a job pass. A missing, expired or wrongly valued secret stays with you and is excluded from that job. It is £149, untested, paid after sign-off.

Sources and limits

  • GitHub: using secrets in workflows Checked 2026-10-11.
    • An unset secret evaluates to an empty string, secrets are not automatically passed to reusable workflows, runs triggered from forks receive no secrets except the built-in token, and workflows triggered by Dependabot cannot read Actions secrets.
  • GitHub: reusing workflows Checked 2026-10-11.
    • Secrets are passed only to a directly called workflow, by name or with inherit for callers in the same organisation, and a missing environment secret resolves to an empty string.
  • GitHub: environments Checked 2026-10-11.
    • Environment secrets are available only to jobs that use the environment, after its protection rules pass.
  • GitHub: automating Dependabot with Actions Checked 2026-10-11.
    • A troubleshooting check for Dependabot-triggered runs is whether the secrets are stored as Dependabot secrets rather than Actions secrets.