# GitHub Actions run-name env not available, and what it can read

> GitHub Actions run-name env not available is a rejected workflow, not a blank title. See the three contexts the key accepts and what to use instead.

Source: https://latchkey.dev/learn/github-actions/github-actions-env-workflow-level-not-visible-in-run-name  
Updated: 2026-09-20

GitHub Actions run-name env not available is a workflow that fails to compile rather than a run that gets a blank name. The key carries a short list of allowed contexts, env is not on it, and an expression naming a context outside the list is rejected while the file is being read.

## What this error means

You added an environment variable to the run name, expecting either the value or an empty string, and instead the workflow stopped running entirely. The annotation is on the file and quotes a name rather than a value. A second, milder version exists where the run name shows literal braces instead of a value, and that one has a different cause: the expression was never treated as an expression, usually because of how it was quoted.

```Message composed by ParseException in actions/runner, with the file and line prefix
The workflow is not valid. .github/workflows/deploy.yml (Line: 4, Col: 11):
Unrecognized named-value: 'env'. Located at position 1 within expression: env.TARGET
```

## Common causes

### The run name referenced a workflow level env value

The commonest one, and it looks reasonable because the `env:` block is a few lines below in the same file. Proximity in the file is not availability in the expression: the key's context list decides, and env is not on it.

### The value was expected to come from a step

A version number computed during the build cannot appear in the run name, because the name is decided before any step runs. No context would help, since the value does not exist at that moment.

### The expression was written but never parsed as one

This is the variant that produces a literal pair of braces in the name rather than an error. It comes from quoting or escaping that stops the reader recognizing an interpolation, which means nothing was rejected because nothing was parsed.

### A repository variable was assumed to be unavailable

The documentation sentence names github and inputs only, so people conclude vars is out and reach for env instead. The schema's context list for the key includes vars, which makes a repository variable the closest thing to a workflow level default that a run name can read.

## How to fix it

### Use a repository variable instead of a workflow env value

Move the value to a repository or organization variable and read it through vars, which is on the key's context list. This is the nearest equivalent to a workflow level default that survives being read before any job exists.

```.github/workflows/deploy.yml (illustrative)
run-name: Deploy ${{ vars.DEPLOY_TARGET }} from ${{ github.ref_name }}
```

### Take the value as a dispatch input

1. Declare the input under `on.workflow_dispatch.inputs` with a type and a default.
2. Read it in `run-name` through the inputs context.
3. Give the input a description, because it now appears in the run name and people will read it as a label.
4. Keep the same input available to the jobs, so the name and the behavior cannot drift apart.

### Put a computed value on the job or in the summary

For anything a step produces, name the job with what is known at job level and write the computed detail to the step summary. The summary is rendered on the run page, which is the surface most people are actually trying to improve when they reach for a dynamic run name.

```.github/workflows/deploy.yml (illustrative)
- run: echo "### Deployed ${VERSION}" >> "$GITHUB_STEP_SUMMARY"
```

### Drop the key and take the default name

When there is nothing available worth putting in it, leave `run-name` out. The documentation records that an omitted or whitespace-only value produces event specific information instead, which for a push is the commit message and for a pull request is its title, and both are usually more informative than a static string.

## How to prevent it

- Check a key's context list before writing an expression into it.
- Keep values that belong in a run name as repository variables or dispatch inputs.
- Use the step summary for anything computed during the run.
- Do not add `run-name` unless it says more than the default would.

## Three contexts, and a documentation sentence that names two

In the published schema, `run-name` is a string definition carrying a context list of exactly three entries: github, inputs and vars. That list is what the expression parser is given when it reads the value, so a name outside it has no definition to match and the parse fails.

The documentation states it slightly more narrowly. The workflow syntax reference says the value can include expressions and can reference the github and inputs contexts, and does not mention vars. The schema is the thing the parser reads, so if you need a repository variable in a run name, the schema is the better guide, and it is worth knowing that the two sources differ here rather than assuming one of them is a typo.

Neither list contains env, and that is not an oversight. A run name is decided when the run is created, before any job has been assigned a machine, so there is no step environment for an env context to describe. The same reasoning excludes steps, runner, job and matrix.

| What you want in the run name | Reachable from `run-name` | What to use |
| --- | --- | --- |
| A value from a workflow level `env:` map | no | a repository variable, or inline the literal |
| The branch or tag that triggered it | yes | `github.ref_name` |
| Who started it | yes | `github.actor` |
| A value typed into a manual dispatch | yes | `inputs.<name>` |
| Something a step computed | no | a job name, or the step summary |

> The key is optional, and the documentation records the fallback: when `run-name` is omitted or holds only whitespace, the run name becomes event specific information, such as the commit message for a push or the pull request title.

## Why this is a compile failure and not a blank name

The reader does not evaluate expressions as it goes. When it meets a scalar that contains an interpolation, it slices out the expression text and parses it against the list of contexts the schema attached to that key. If the parse throws, the reader records the exception as a template error at the token's position, which is what makes the whole file invalid.

The message you get is assembled by the expression parser, not by the schema reader. Its description is the phrase for an unrecognized named value, and because a token was involved it goes on to quote the name, give the position within the expression and repeat the expression itself. That is why the text names env and then shows you the expression it came from.

Our page on that message is the one that covers the family it belongs to and the table of which contexts each workflow key accepts. If you are here because you have the message and the key involved was not run-name, that is the page to read.

## Getting a computed value into the run, when the name cannot have it

Once you accept that the run name is fixed before any job starts, the question becomes where else a computed value can go. There are three good answers and they suit different purposes.

A job name can carry matrix values and anything reachable at job level, which is a wider list than run-name has. For a value a step computes, the job summary is the honest surface: append to the file named by the step summary variable and it renders on the run page, which is where most people were looking for the run name to tell them something anyway.

If the value is genuinely known before the run starts, promote it to something run-name can read. A repository variable is readable through vars, and a dispatch input is readable through inputs, and both exist before the run is created. That is the only way to make the name itself dynamic.

```.github/workflows/deploy.yml (illustrative)
run-name: Deploy ${{ inputs.target }} by @${{ github.actor }}

on:
  workflow_dispatch:
    inputs:
      target:
        type: string
        required: true
```

## Why there is no recorded run on this page

The subject of this page is a field that only exists once a run has been created, and the failure prevents the run from being created. There is no name to photograph and no job to log. A recording would have to be of a workflow whose run-name compiled, which shows the working case and says nothing about the rejected one.

Everything asserted here is readable without a run: the context list attached to the key in the schema, the documentation sentence that names two of the three, the reader path that turns a parse failure into a template error, and the parser that formats the message. The sibling pages on env scope and on the context table carry the rest of the family.

## FAQ

### Can run-name read the env context?

No. The key carries a context list of github, inputs and vars in the published schema, and env is not on it. An expression naming a context outside that list fails to parse, and the reader records the failure as a template error, so the workflow file is invalid rather than the name being blank.

### Can run-name read a repository variable?

The schema's context list for the key includes vars, so yes. The documentation sentence mentions only github and inputs, which is narrower than the schema, and it is worth knowing the two differ before concluding a variable is unavailable.

### Why does my run name show the expression text instead of a value?

Because the reader never recognized it as an expression. That is a quoting or escaping problem rather than a context problem, and it produces literal text rather than an error, because nothing was parsed and therefore nothing could be rejected.

### How do I put a version computed during the build into the run?

You cannot put it in the run name, which is fixed before any job starts. Write it to the step summary, which renders on the run page, or use it in a job name if it is available at job level. A value that does not exist yet has no context that could carry it.

## References

- [GitHub Actions: workflow syntax, run-name](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax)
- [actions/runner: the published workflow schema, the run-name context list](https://github.com/actions/runner/blob/main/src/Sdk/WorkflowParser/workflow-v1.0.json)
- [actions/runner: TemplateReader.cs, expression parsing against the allowed context](https://github.com/actions/runner/blob/main/src/Sdk/DTObjectTemplating/ObjectTemplating/TemplateReader.cs)
- [GitHub Actions: contexts reference](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
