Introduction

The workflow_dispatch event in GitHub Actions allows manual triggering of workflows through the GitHub UI, CLI, or API. Unlike push or pull_request events that have predictable contexts, workflow_dispatch accepts user-defined inputs that are validated against a schema before the workflow executes. This validation ensures type safety, required field presence, and choice constraints—but it also means that incorrectly formatted inputs cause the dispatch to fail before the workflow even starts.

When input validation fails, GitHub returns an HTTP 422 error for API calls, or displays an error message in the UI. No workflow run is created, making it difficult to diagnose issues through standard workflow logs. The failure happens at the dispatch layer, not inside the workflow execution, so debugging requires understanding the input schema definition and comparing it against the actual payload being sent.

Understanding the input type system—string, boolean, number, choice, and environment—is essential for correctly defining and invoking workflow_dispatch workflows. Each type has specific validation rules, and mismatches between expected and provided values cause predictable but sometimes confusing errors.

Symptoms

When workflow_dispatch input validation fails, you will observe these symptoms:

  • Manual workflow triggers from GitHub UI show "Inputs are invalid" or specific field errors
  • gh workflow run command returns error without creating a run
  • API calls to create workflow dispatch return HTTP 422 Unprocessable Entity
  • The workflow run list shows no new run despite the trigger attempt
  • Error messages reference specific input names with "required", "invalid", or "not found"
  • Previous versions of the workflow dispatch work but new versions fail
  • Choice inputs reject values that look correct but don't match exactly

Common error messages from GitHub CLI:

bash
gh: Input validation failed: environment: must be one of ["staging", "production"]
gh: Input validation failed: deploy: Required input "environment" not provided
gh: workflow run failed: HTTP 422: Invalid request.

API error responses:

```json { "message": "Invalid request.\n\nNo event type configured for workflow dispatch", "documentation_url": "https://docs.github.com/rest/reference/actions#create-a-workflow-dispatch-event" }

{ "message": "Invalid request.\n\ninputs.deploy: must be a boolean", "documentation_url": "https://docs.github.com/rest/reference/actions" } ```

GitHub UI error display:

bash
Warning: Input validation failed
- environment: Value must be one of: staging, production
- count: Value must be a number
- dry-run: Value must be true or false

Common Causes

Several factors cause workflow_dispatch input validation failures:

  1. 1.Missing required inputs: The workflow definition marks an input as required: true, but the dispatch request doesn't include it. Required inputs must always be provided unless a default is specified.
  2. 2.Choice value mismatch: For type: choice inputs, the provided value must exactly match one of the options array entries. Case differences, typos, or similar-but-different values are rejected.
  3. 3.Type mismatch: Sending a string where a boolean or number is expected. This commonly happens when CLI flags are passed incorrectly or API payloads use string values in JSON.
  4. 4.Workflow file on wrong branch: The dispatch is triggered against a branch where the workflow file either doesn't exist or has a different input schema than expected.
  5. 5.Outdated caller scripts: After workflow input definitions change, external scripts or CI systems that dispatch workflows may still send the old input format.
  6. 6.Missing workflow file: Attempting to dispatch a workflow that doesn't exist or has been renamed without updating the caller.
  7. 7.Environment reference errors: When using environment: ${{ inputs.env }} style references, the actual environment names in GitHub must exist.
  8. 8.JSON payload formatting issues: For API dispatches, incorrect JSON encoding (e.g., strings for numbers, missing quotes) causes validation failures.

Step-by-Step Fix

Follow these steps to diagnose and resolve workflow_dispatch input validation errors:

Step 1: Inspect the current workflow input schema

First, examine the exact input definitions on the branch being targeted:

```bash # View workflow file from the target branch gh api repos/:owner/:repo/contents/.github/workflows/deploy.yml?ref=main --jq '.content' | base64 -d

# Or check locally cat .github/workflows/deploy.yml ```

Example workflow with various input types:

yaml
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        type: choice
        options:
          - staging
          - production
      version:
        description: 'Version to deploy'
        required: true
        type: string
      dry-run:
        description: 'Perform dry run only'
        required: false
        type: boolean
        default: false
      replicas:
        description: 'Number of replicas'
        required: false
        type: number
        default: 3

Step 2: Validate required inputs are provided

Ensure all required: true inputs without defaults are included:

```bash # Wrong: Missing required 'environment' input gh workflow run deploy.yml --ref main -f version=1.0.0 # Error: Required input "environment" not provided

# Correct: Provide all required inputs gh workflow run deploy.yml --ref main \ -f environment=staging \ -f version=1.0.0 ```

Check which inputs are required:

bash
# Extract required inputs from workflow
yq '.on.workflow_dispatch.inputs | to_entries | map(select(.value.required == true)) | .[].key' .github/workflows/deploy.yml

Step 3: Match choice values exactly

Choice inputs require exact matches to defined options:

yaml
# Workflow definition
inputs:
  environment:
    type: choice
    options:
      - staging
      - production

```bash # Wrong: Case mismatch gh workflow run deploy.yml -f environment=Staging # Error: must be one of ["staging", "production"]

# Wrong: Similar but not exact gh workflow run deploy.yml -f environment=prod # Error: must be one of ["staging", "production"]

# Correct: Exact match gh workflow run deploy.yml -f environment=production ```

Step 4: Use correct types for boolean and number inputs

Boolean inputs require literal true/false values:

```bash # For boolean inputs, use -F for boolean true gh workflow run deploy.yml -F dry-run -f environment=staging

# Or explicitly gh workflow run deploy.yml -f dry-run=true -f environment=staging

# Wrong: String value for boolean gh workflow run deploy.yml -f dry-run=yes # Error: Value must be true or false ```

For API calls, use proper JSON types:

```bash # Correct: Boolean as JSON boolean curl -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/owner/repo/actions/workflows/deploy.yml/dispatches \ -d '{"ref":"main","inputs":{"environment":"staging","dry-run":true}}'

# Wrong: Boolean as string curl -X POST \ -d '{"ref":"main","inputs":{"environment":"staging","dry-run":"true"}}' # Error: must be a boolean ```

Number inputs require numeric values:

```bash # Correct: Number input gh workflow run deploy.yml -f replicas=5 -f environment=staging

# For API, use JSON number curl -X POST \ -d '{"ref":"main","inputs":{"environment":"staging","replicas":5}}' ```

Step 5: Verify the workflow exists on the target branch

Ensure the workflow file exists on the branch you're dispatching to:

```bash # Check if workflow file exists on branch gh api repos/:owner/:repo/contents/.github/workflows/deploy.yml?ref=main

# List all workflows on the branch gh api repos/:owner/:repo/actions/workflows --jq '.workflows[].path' ```

If the workflow was renamed or moved:

```bash # Find workflows by name pattern gh api repos/:owner/:repo/actions/workflows --jq '.workflows[] | select(.name | contains("deploy")) | .path'

# Use the correct workflow filename gh workflow run new-deploy.yml -f environment=staging ```

Step 6: Test with minimal inputs

Isolate the failing input by testing incrementally:

```bash # Start with only required inputs gh workflow run deploy.yml -f environment=staging -f version=1.0.0

# If that works, add optional inputs one at a time gh workflow run deploy.yml -f environment=staging -f version=1.0.0 -F dry-run

# Add more optional inputs gh workflow run deploy.yml -f environment=staging -f version=1.0.0 -F dry-run -f replicas=5 ```

Step 7: Debug API payload format

For API-triggered dispatches, validate the JSON payload:

```bash # Validate JSON syntax echo '{"ref":"main","inputs":{"environment":"staging"}}' | jq .

# Check input types echo '{"ref":"main","inputs":{"environment":"staging","replicas":5,"dry-run":true}}' | jq '.inputs'

# Test with curl verbose output curl -v -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/owner/repo/actions/workflows/deploy.yml/dispatches \ -d '{"ref":"main","inputs":{"environment":"staging","version":"1.0.0"}}' ```

Step 8: Check for recent workflow changes

Compare workflow definition with previous versions:

```bash # View recent commits to workflow file gh api repos/:owner/:repo/commits --path .github/workflows/deploy.yml --jq '.[].sha' | head -5

# Compare current version with previous gh api repos/:owner/:repo/compare/HEAD~5...HEAD --jq '.files[] | select(.filename == ".github/workflows/deploy.yml") | .patch' ```

Verification

After fixing input validation issues, verify the workflow dispatch succeeds:

```bash # Trigger workflow with corrected inputs gh workflow run deploy.yml \ --ref main \ -f environment=staging \ -f version=1.0.0 \ -F dry-run

# Verify run was created gh run list --workflow=deploy.yml --limit 1

# Watch the run gh run watch

# Check run details gh run view --json name,status,conclusion ```

For API-triggered dispatches:

```bash # Successful dispatch returns 204 No Content curl -w "%{http_code}" -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/owner/repo/actions/workflows/deploy.yml/dispatches \ -d '{"ref":"main","inputs":{"environment":"staging","version":"1.0.0"}}' # Expected: 204

# List recent runs to confirm gh run list --workflow=deploy.yml --limit 3 ```

Verify workflow received correct input values:

yaml
# Add debug step to workflow
steps:
  - name: Debug inputs
    run: |
      echo "Environment: ${{ inputs.environment }}"
      echo "Version: ${{ inputs.version }}"
      echo "Dry run: ${{ inputs.dry-run }}"
      echo "Replicas: ${{ inputs.replicas }}"
bash
# Check debug output in logs
gh run view --log | grep -A5 "Debug inputs"

Prevention

To prevent workflow_dispatch input validation errors:

  1. 1.Provide defaults for optional inputs: Define sensible defaults for inputs that can have them.
yaml
inputs:
  dry-run:
    type: boolean
    default: false
  replicas:
    type: number
    default: 3
  1. 1.Use choice inputs for constrained values: Prefer type: choice with explicit options over string inputs for environments, regions, or other constrained values.
yaml
inputs:
  environment:
    type: choice
    options:
      - staging
      - production
    required: true
  1. 1.Document inputs clearly: Use the description field to document expected values and formats.
yaml
inputs:
  version:
    description: 'Semantic version string (e.g., 1.2.3)'
    required: true
    type: string
  1. 1.Keep dispatch scripts in sync: When modifying workflow inputs, immediately update any scripts or CI pipelines that dispatch to that workflow.
bash
# Create a test script alongside the workflow
cat > scripts/dispatch-deploy.sh << 'EOF'
#!/bin/bash
gh workflow run deploy.yml \
  --ref main \
  -f environment="${1:-staging}" \
  -f version="$2" \
  -F dry-run="${3:-false}"
EOF
  1. 1.Add input validation in the workflow: Even with schema validation, add workflow-level checks for complex validation.
yaml
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Validate version format
        run: |
          if [[ ! "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "Error: Version must be semantic (e.g., 1.2.3)"
            exit 1
          fi
  1. 1.Test workflow dispatch after changes: Always test manual dispatch after modifying workflow input definitions.
bash
# Quick test script
gh workflow run deploy.yml -f environment=staging -f version=test
gh run watch
  1. 1.Use GitHub CLI input file support: For complex inputs, use JSON input files to ensure proper formatting.

```bash # Create inputs file cat > inputs.json << 'EOF' { "environment": "staging", "version": "1.0.0", "dry-run": true, "replicas": 3 } EOF

# Use the inputs file gh workflow run deploy.yml --inputs-file inputs.json ```

  • [WordPress troubleshooting: Fix IAM Access Denied 403 - Complete Tro](fix-iam-access-denied-403)
  • [GitHub Actions Artifact Expired or 403 Download Failed](github-actions-artifact-expired-403-download-failed)
  • [Fix Github Actions Artifact Upload Failed File Too Large 5gb Limit Issue in GitHub Actions](github-actions-artifact-upload-failed-file-too-large-5gb-limit)
  • [Fix Github Actions Aws S3 Deploy Credentials Expired Rotate Issue in GitHub Actions](github-actions-aws-s3-deploy-credentials-expired-rotate)
  • [Fix Github Actions Cache Evicted Manually Workflow Fails Download Issue in GitHub Actions](github-actions-cache-evicted-manually-workflow-fails-download)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "GitHub Actions workflow_dispatch Input Validation Failed", "description": "Resolve GitHub Actions workflow_dispatch input validation errors by aligning manual trigger payloads with required, choice, boolean, and string input definitions.", "url": "https://www.fixwikihub.com/github-actions-workflow-dispatch-input-validation-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-01-23T05:32:28.369Z", "dateModified": "2026-01-23T05:32:28.369Z" } </script>