# GitHub Actions unrecognized named-value: inputs, and the context that is missing

> Fix GitHub Actions unrecognized named-value: inputs, the error that means no trigger in this file ever declared an input for the context to hold.

Source: https://latchkey.dev/learn/github-actions/gha-inputs-context-not-available-non-reusable  
Updated: 2026-09-20

GitHub Actions unrecognized named-value: inputs has one cause, and it is a scope problem rather than a spelling one. The file you are editing never declared an input under a trigger that creates one, so there is no `inputs` context for the expression parser to resolve, and it rejects the name before the workflow runs.

## What this error means

The workflow is invalid and never starts. The message names `inputs` as the unrecognized name and points at the line, and the confusing part is that the identical expression works in the file next door. It does, because the context is created by the trigger rather than by the workflow. A file with `on: workflow_call` and a declared input has an `inputs` context; the same file triggered only by `push` does not, and the parser treats the name as it would treat any word it has never heard of. Two other shapes land on this message for the same reason. A local composite action whose metadata is written like a workflow, and a workflow that declares nothing and reads values out of the event payload instead, which is a different context with a different name.

```Annotation, quoted from nicholaslee119/claude-code-github-action#1
nicholaslee119/claude-code-github-action/0.1.0/action.yml (Line: 49, Col: 14):
Unrecognized named-value: 'inputs'. Located at position 1 within expression: inputs.issue-number
```

## Common causes

### No trigger in this file declares an input

The ordinary case. The expression was copied from a reusable workflow into a file triggered by `push`, `schedule` or `workflow_run`, where the context does not exist. Nothing about the expression is wrong, and nothing about the expression will fix it.

### The file is a composite action written like a workflow

A local action under `.github/actions/` declares its inputs at the top level of `action.yml`, not under an `on:` key. actions/runner#3307 is this exact shape: a file with `workflow_dispatch` and `workflow_call` blocks, called with `uses: ./.github/actions/dev`, reporting the unrecognized name.

### The value arrives in the event payload instead

A client payload, a pull request body or a triggering run is part of the event, and the event is reached through the `github` context. The `inputs` context only ever holds what the workflow itself declared, so a value nobody declared is not going to appear in it.

### The input is declared under the other trigger

A file with both `workflow_call` and `workflow_dispatch` needs the input in both blocks. In our experience this surfaces when a reusable workflow is later made runnable by hand: the call path works, the manual path is rejected, and the difference is four lines nobody added.

## How to fix it

### Add the declaration to the trigger that starts this run

1. Decide how this file is started: called by another workflow, run by hand, or both.
2. Declare the input under `on.workflow_call.inputs` or `on.workflow_dispatch.inputs`, with a type.
3. Keep the name identical in both blocks so one expression covers both paths.

### Move the declaration to the top level for a composite action

An action reads its inputs from an `inputs:` map beside `name` and `runs`, and a composite action reaches them through the same `inputs` context. There is no `on:` key in an action, so a workflow pasted into `action.yml` will always be rejected.

```.github/actions/deploy/action.yml (illustrative)
name: deploy
inputs:
  environment:
    description: target environment
    required: true
runs:
  using: composite
  steps:
    - run: ./deploy.sh ${{ inputs.environment }}
      shell: bash
```

### Read the event where the value actually is

For a payload that nobody declared, use the `github` context and the field the event carries. This is the right answer for `repository_dispatch` and `workflow_run`, and it is the only answer for an event with no input mechanism at all.

```.github/workflows/deploy.yml (illustrative)
- run: ./deploy.sh "$TARGET"
        env:
          TARGET: ${{ github.event.client_payload.environment }}
```

### Give every input a default before you depend on it

A declared input with a default keeps the manual path usable without a form full of required fields, and it keeps a caller that omits the value from failing validation. Declare the type as well, because the caller is checked against it.

## How to prevent it

- Declare an input under its trigger in the same commit that first references it.
- Prefer the `inputs` context over the event payload for dispatch and call inputs, so one expression covers both.
- Keep composite action metadata separate in your head from workflow files: no `on:` key, inputs at the top level.
- Lint with a tool that knows which contexts each trigger creates, rather than a generic YAML validator.

## A minimal workflow that produces it

This file is written for this page and has never been run. It is valid YAML, the expression syntax is correct, and the name is spelled the way the documentation spells it. The only thing missing is a trigger that declares an input, and without one the context does not exist for this file.

```.github/workflows/deploy.yml (illustrative)
name: deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh ${{ inputs.environment }}
```

## Where the inputs context exists

The contexts reference draws the boundary twice. First by definition: the `inputs` context "contains input properties passed to an action, to a reusable workflow, or to a manually triggered workflow". Then by scope: "The properties in the `inputs` context are defined in the workflow file. They are only available in a reusable workflow or in a workflow triggered by the `workflow_dispatch` event."

So two keys create it, and both of them live under `on`. For a reusable workflow the names and types come from the `workflow_call` configuration and the values arrive from `jobs.<job_id>.with` in the caller. For a manual run they come from `workflow_dispatch`. A workflow triggered by anything else has no `inputs` at all, and the parser says so rather than handing you an empty value.

## Declare the input under the trigger that runs the file

The fix is to add the declaration, not to change the expression. A `workflow_dispatch` input takes a type, and the workflow syntax reference limits the choice: "This must be one of: `boolean`, `choice`, `number`, `environment` or `string`." Once declared, the context is populated for every job and step in the run, and the same expression that was rejected now resolves.

A file can carry both triggers at once when it is called by another workflow and also run by hand. Declare the input under each, because the two configurations are read separately, and keep the names identical so the expression does not have to care which way the run started.

```.github/workflows/deploy.yml, corrected (illustrative)
name: deploy
on:
  workflow_dispatch:
    inputs:
      environment:
        type: string
        default: staging
  workflow_call:
    inputs:
      environment:
        type: string
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh ${{ inputs.environment }}
```

## The other place values arrive from

When a value comes in on an event payload rather than through a declared input, it is not in this context and never will be. A `repository_dispatch` carries a client payload, a `workflow_run` carries the run that triggered it, and both are read through the `github` context. The manual trigger is the one case where both work, because a dispatch input is written into the event payload as well, which is why older workflows read `github.event.inputs` and newer ones read `inputs`.

Prefer the declared context when you have the choice. It is typed, it is populated the same way whether the run was called or dispatched, and it is available in keys where the event payload is awkward to reach.

> The same message with a different name in quotes is the same class of problem: [GitHub Actions unrecognized named-value](/learn/github-actions/gha-bad-expression-context-access).

## Why there is no recorded run on this page

The parser rejects the file before a job exists, so there is no log from a runner to record and nothing transient for a runner to repair. The annotation quoted above comes from a public issue and names an `action.yml`, because the same parser and the same message cover both file kinds; actions/runner#3307 reports the identical line, `Unrecognized named-value: 'inputs'`, from a workflow-shaped file used as a local action.

## FAQ

### Why is the inputs context not recognized in my workflow?

Because nothing in that file declares an input. The contexts reference says the properties "are only available in a reusable workflow or in a workflow triggered by the `workflow_dispatch` event", so a file triggered by `push` or `schedule` has no such context and the parser rejects the name rather than returning an empty value.

### What is the difference between inputs and github.event.inputs?

The first is a declared, typed context created by `workflow_call` or `workflow_dispatch`. The second is a field on the event payload, which only exists for a manual run. A dispatch input appears in both, which is why both forms are seen in the wild; a reusable workflow input appears only in the declared context.

### Where does a composite action declare its inputs?

At the top level of `action.yml`, under an `inputs:` key, rather than under an `on:` key the way a reusable workflow declares them. actions/runner#3307 is the failure mode when they are declared the other way: a workflow-shaped file placed under `.github/actions/` and called with `uses:`, reporting `Unrecognized named-value: 'inputs'` because the parser never saw a declaration.

### Which triggers populate the inputs context?

Two: `workflow_call`, where the names and types come from the called workflow and the values from `jobs.<job_id>.with` in the caller, and `workflow_dispatch`, where they come from the manual run form. Every other event carries its data in the payload, which you read through the `github` context instead.

## References

- [GitHub Actions: contexts reference, inputs context](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#inputs-context)
- [GitHub Actions: workflow syntax, on.workflow_dispatch.inputs](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_dispatchinputs)
- [actions/runner#3307: Unrecognized named-value: inputs from a local action](https://github.com/actions/runner/issues/3307)
- [GitHub Actions: metadata syntax, action inputs](https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs)

---

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
