Skip to content
Latchkey LogoLatchkey home

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

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.

Which triggers create the inputs context and where event payload values live instead
Two triggers create the context. Everything else has to read the event payload, which is a different name with different contents.

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

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 }}

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.

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.

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.

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.

Frequently asked questions

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.

Related guides

References

One runs-on line in a reusable workflow moves every caller onto Latchkey. Start free → 30-day trial · No credit card