Official agent skill

Error Messages

by github in github/gh-aw

Write consistent, actionable validation error messages in gh-aw.

OfficialMITAuto-check passedDevelopment

Install Error Messages

skills CLI
$ npx skills add github/gh-aw --skill error-messages -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install github/gh-aw error-messages --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/github/gh-aw.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/error-messages .claude/skills/error-messages && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
error-messages
GitHub stars
5.3k
Token cost
~2.3k tokens
SKILL.md length
632 words
Files
2
Skills in repo
52
Repo updated
First seen
Licence
MIT

At a glance

Write consistent, actionable validation error messages in gh-aw.

  • Works in 3 steps: What's wrong? - Clearly state the… → What's expected? - Explain the valid… → How to fix it? - Provide a concrete…
  • Development work in your project
  • SKILL.md covers Error Message Template, Constructive Language, When to use NewValidationError… and Suggestion Text Checklist, plus 10 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Error Messages is an agent skill from github/gh-aw, published by the product's own GitHub organization. Write consistent, actionable validation error messages in gh-aw.

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `ssl.json`).

It sits in Development. It works with GitHub and Git. The repository describes itself as: GitHub Agentic Workflows. The licence is MIT.

When your agent uses it

  • Development work in your project

Example prompts

  • “/error-messages”

Requirements

  • Node.js

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. What's wrong? - Clearly state the validation error
  2. What's expected? - Explain the valid format or values
  3. How to fix it? - Provide a concrete example of correct usage

What it can do on your machine

Read from SKILL.md and the folder at commit eb63040. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are go).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Error Messages loads about 2.3k tokens when it runs. Until then it costs about 20 tokens; SKILL.md has 632 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~20
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from github/gh-aw at commit eb63040, republished under its MIT licence (© github). 632 words, ~2,294 tokens.

Download SKILL.mdSave it as .claude/skills/error-messages/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
error-messages
description
Write consistent, actionable validation error messages in gh-aw.

Error Message Style Guide

Use this format for gh-aw validation errors. Keep messages clear, actionable, and example-driven.

Error Message Template

[what's wrong]. [what's expected]. [example of correct usage]

Make each error message answer three questions:

  1. What's wrong? - Clearly state the validation error
  2. What's expected? - Explain the valid format or values
  3. How to fix it? - Provide a concrete example of correct usage

Constructive Language

Avoid standalone negative wording. Pair it with expected behavior and a concrete fix.

Avoid only-negative wordingPrefer constructive wording
invalidexpected + valid format/options
cannotrequires + precondition
mustshould + example
failedaction context + recovery step

❌ invalid repo format: %s
✅ invalid repo format '%s' — expected 'owner/repo' format (for example: 'github/gh-aw')

❌ not in a git repository
✅ not in a git repository — run 'git init' or 'cd' to a git repository

When to use NewValidationError vs fmt.Errorf

  • Use NewValidationError(field, value, reason, suggestion) in *_validation.go logic.
    • Use field for the exact config path
    • Use reason for what failed
    • Use suggestion for an actionable fix with an example
  • Use fmt.Errorf for operational/wrapping errors (%w) where you are propagating a lower-level failure with context.
  • Avoid generic wrappers like fmt.Errorf("failed to X: %w", err) unless you add recovery guidance.

Suggestion Text Checklist

Every suggestion should:

  1. Explain what to change
  2. Include a minimal valid YAML/code example
  3. Use ✓/✗ markers when ambiguity is likely

Example:

text
Use one supported engine.
✓ Example:
engine: copilot

✗ Avoid:
engine: unknown

YAML Example Guidelines

  • Keep examples minimal and valid YAML
  • Use real frontmatter field names
  • Quote only when YAML requires it
  • Prefer 2-space indentation

Good Examples

These examples follow the template and provide actionable guidance:

Time Delta Validation (from time_delta.go)
go
return nil, fmt.Errorf("invalid time delta format: +%s. Expected format like +25h, +3d, +1w, +1mo, +1d12h30m", deltaStr)

✅ Why it's good:

  • Clearly identifies the invalid input
  • Lists multiple valid format examples
  • Shows combined formats (+1d12h30m)
Type Validation with Example
go
return "", fmt.Errorf("manual-approval value must be a string, got %T. Example: manual-approval: \"production\"", val)

✅ Why it's good:

  • Shows actual type received (%T)
  • Provides concrete YAML example
  • Uses proper YAML syntax with quotes
Enum Validation with Options
go
return fmt.Errorf("invalid engine: %s. Valid engines are: copilot, claude, codex, custom. Example: engine: copilot", engineID)

✅ Why it's good:

  • Lists all valid options
  • Provides simplest example
  • Uses consistent formatting
MCP Configuration
go
return fmt.Errorf("tool '%s' mcp configuration must specify either 'command' or 'container'. Example:\ntools:\n  %s:\n    command: \"npx @my/tool\"", toolName, toolName)

✅ Why it's good:

  • Explains mutual exclusivity
  • Shows realistic tool name
  • Formats multi-line YAML example

Bad Examples

These examples lack clarity or actionable guidance:

Too Vague
go
return fmt.Errorf("invalid format")

❌ Problems:

  • Doesn't specify what format is invalid
  • Doesn't explain expected format
  • No example provided
Missing Example
go
return fmt.Errorf("manual-approval value must be a string")

❌ Problems:

  • States requirement but no example
  • User doesn't know proper YAML syntax
  • Could be clearer about type received
Incomplete Information
go
return fmt.Errorf("invalid engine: %s", engineID)

❌ Problems:

  • Doesn't list valid options
  • No guidance on fixing the error
  • User must search documentation
Show full SKILL.md (317 more words)Show less

When to Include Examples

Always include examples for:

  1. Format/Syntax Errors - Show the correct syntax

    go
    fmt.Errorf("invalid date format. Expected: YYYY-MM-DD HH:MM:SS. Example: 2024-01-15 14:30:00")
  2. Enum/Choice Fields - List all valid options

    go
    fmt.Errorf("invalid permission level: %s. Valid levels: read, write, none. Example: permissions:\n  contents: read", level)
  3. Type Mismatches - Show expected type and example

    go
    fmt.Errorf("timeout-minutes must be an integer, got %T. Example: timeout-minutes: 10", value)
  4. Complex Configurations - Provide complete valid example

    go
    fmt.Errorf("invalid MCP server config. Example:\nmcp-servers:\n  my-server:\n    command: \"node\"\n    args: [\"server.js\"]")

When Examples May Be Optional

Examples can be omitted when:

  1. Error is from wrapped error - When wrapping another error with context

    go
    return fmt.Errorf("failed to parse configuration: %w", err)
  2. Error is self-explanatory with clear context

    go
    return fmt.Errorf("duplicate unit '%s' in time delta: +%s", unit, deltaStr)
  3. Error points to specific documentation

    go
    return fmt.Errorf("unsupported feature. See https://docs.example.com/features")

Formatting Guidelines

Use Type Verbs for Dynamic Content
  • %s - strings
  • %d - integers
  • %T - type of value
  • %v - general value
  • %w - wrapped errors
Multi-line Examples

For YAML configuration examples spanning multiple lines:

go
fmt.Errorf("invalid config. Example:\ntools:\n  github:\n    mode: \"remote\"")
Quoting in Examples

Use proper YAML syntax in examples:

go
// Good - shows quotes when needed
fmt.Errorf("Example: name: \"my-workflow\"")

// Good - shows no quotes for simple values
fmt.Errorf("Example: timeout-minutes: 10")
Consistent Terminology

Use the same field names as in YAML:

go
// Good - matches YAML field name
fmt.Errorf("timeout-minutes must be positive")

// Bad - uses different name
fmt.Errorf("timeout must be positive")

Error Message Testing

All improved error messages should have corresponding tests:

go
func TestErrorMessageQuality(t *testing.T) {
    err := validateSomething(invalidInput)
    require.Error(t, err)
    
    // Error should explain what's wrong
    assert.Contains(t, err.Error(), "invalid")
    
    // Error should include expected format or values
    assert.Contains(t, err.Error(), "Expected")
    
    // Error should include example
    assert.Contains(t, err.Error(), "Example:")
}

Migration Strategy

When improving existing error messages:

  1. Identify the error - Find validation error that lacks clarity
  2. Analyze context - Understand what's being validated
  3. Apply template - Add what's wrong + expected + example
  4. Add tests - Verify error message content
  5. Update comments - Document the validation logic

Examples by Category

Format Validation
go
// Time deltas
fmt.Errorf("invalid time delta format: +%s. Expected format like +25h, +3d, +1w, +1mo, +1d12h30m", input)

// Dates
fmt.Errorf("invalid date format: %s. Expected: YYYY-MM-DD or relative like -1w. Example: 2024-01-15 or -7d", input)

// URLs
fmt.Errorf("invalid URL format: %s. Expected: https:// URL. Example: https://api.example.com", input)
Type Validation
go
// Boolean expected
fmt.Errorf("read-only must be a boolean, got %T. Example: read-only: true", value)

// String expected
fmt.Errorf("workflow name must be a string, got %T. Example: name: \"my-workflow\"", value)

// Object expected
fmt.Errorf("permissions must be an object, got %T. Example: permissions:\n  contents: read", value)
Choice/Enum Validation
go
// Engine selection
fmt.Errorf("invalid engine: %s. Valid engines: copilot, claude, codex, custom. Example: engine: copilot", id)

// Permission levels
fmt.Errorf("invalid permission level: %s. Valid levels: read, write, none. Example: contents: read", level)

// Tool modes
fmt.Errorf("invalid mode: %s. Valid modes: local, remote. Example: mode: \"remote\"", mode)
Configuration Validation
go
// Missing required field
fmt.Errorf("tool '%s' missing required 'command' field. Example:\ntools:\n  %s:\n    command: \"node server.js\"", name, name)

// Mutually exclusive fields
fmt.Errorf("cannot specify both 'command' and 'container'. Choose one. Example: command: \"node server.js\"")

// Invalid combination
fmt.Errorf("http MCP servers cannot use 'container' field. Example:\ntools:\n  my-http:\n    type: http\n    url: \"https://api.example.com\"")

References

  • Excellent example to follow: pkg/workflow/time_delta.go
  • Pattern inspiration: Go standard library error messages
  • Testing examples: pkg/workflow/*_test.go

Tools

When writing error messages, consider:

  • The user's perspective (what do they need to fix it?)
  • The context (where in the workflow is the error?)
  • The documentation (should we reference specific docs?)
  • The complexity (is multi-line example needed?)

© github, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in .github/skills/error-messages of github/gh-aw.

  • SKILL.md
  • ssl.json

Open the folder on GitHubat commit eb63040

Compare with similar skills

Error Messages next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Error Messages compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Error Messages this skillgithub/gh-aw5.3k—~2.3kAutomated safety check: PassMIT
Contributor-First PR MergeHKUDS/OpenHarness16k1 repos~847Automated safety check: PassMIT
Create Pull Requestcline/cline70k1 repos~1.6kAutomated safety check: PassApache-2.0
Pull Request Title and Body Writeropeninterpreter/openinterpreter69k2 repos~1.1kAutomated safety check: PassApache-2.0
Draft Release Notesjamiepine/voicebox57k—~941Automated safety check: PassMIT
PR Review State Fetchprisma/orm48k—~767Automated safety check: PassApache-2.0

Similar skills

  • Merges external GitHub pull requests while keeping the original author credited, and fixes conflicts after the merge instead of rewriting the contribution.

    16k GitHub starsUsed in 1 repo~847 tokens
    DevelopmentAuto-check passed
  • Opens a GitHub pull request from your current branch with the gh CLI, after reviewing the commits and diff and gathering the details the PR needs.

    70k GitHub starsUsed in 1 repo~1.6k tokens
    DevelopmentAuto-check passed
  • Pull Request Title and Body Writer

    openinterpreter/openinterpreter

    Rewrites the title and body of one or more pull requests with gh, leading with why the change was made, then what changed, and describing only the net result.

    69k GitHub starsUsed in 2 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Draft Release Notes

    jamiepine/voicebox

    Writes or refreshes the Unreleased section of CHANGELOG.md as a themed narrative built from the commits, PRs and diff since the last version tag.

    57k GitHub stars~941 tokensUpdated today
    DevelopmentAuto-check passed
  • Official

    Fetches a pull request's canonical review state as JSON, validates it, and renders markdown, a text summary and triage target files from it using bundled scripts.

    48k GitHub stars~767 tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Publishes curated, bilingual release notes for an existing Mole version tag with gh release edit, including contributor thanks and reactions, after the release workflow finishes.

    69k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check passed

More from github/gh-aw

All 52 skills in this repo
  • Official

    Drives a real browser from the command line with playwright-cli to open pages, interact, mock requests, save state and work with Playwright tests.

    5.3k GitHub starsUsed in 23 repos~2.8k tokens
    Auto-check passed
  • Official

    Designs and verifies a deterministic grader that measures whether a GitHub Agentic Workflow run reached its real-world or repository outcome.

    5.3k GitHub stars~6.8k tokensUpdated today
    Auto-check passed
  • Official

    Scaffolds, edits, reloads and debugs a canvas extension that the GitHub Copilot CLI can open in its side panel.

    5.3k GitHub stars~3.7k tokensUpdated today
    Auto-check passed
  • Official

    Drives an open pull request to merge-ready from inside a GitHub Copilot cloud agent, resolving review threads and local checks concurrently, without merging or retriggering CI.

    5.3k GitHub stars~3.8k tokensUpdated today
    Auto-check: warnings
  • Official

    Bumps gh-aw's pinned gh-aw-firewall version, rebuilds generated artifacts, and flags upstream spec or schema changes that need follow-up work.

    5.3k GitHub stars~899 tokensUpdated today
    Auto-check passed
  • Official

    Guide to the console struct tag system in gh-aw: headers, titles, number and cost formats, omitempty, and how structs, slices and maps render in the terminal.

    5.3k GitHub stars~736 tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Error Messages

What does Error Messages do?

Write consistent, actionable validation error messages in gh-aw. Error Messages is an agent skill from github/gh-aw, published by the product's own GitHub organization. Write consistent, actionable validation error messages in gh-aw.

When should I use Error Messages?

Error Messages fits situations like: development work in your project.

How do I install Error Messages in Claude Code?

Run `npx skills add github/gh-aw --skill error-messages -a claude-code`. Or copy the skill folder (.github/skills/error-messages in github/gh-aw) into .claude/skills/error-messages in your project. Claude Code loads it when a task matches its description.

How do I install Error Messages in Codex?

Run `npx skills add github/gh-aw --skill error-messages -a codex`. Or copy the skill folder (.github/skills/error-messages in github/gh-aw) into .agents/skills/error-messages in your project. Codex loads it when a task matches its description.

Can I use Error Messages in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add github/gh-aw --skill error-messages -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/error-messages, .gemini/skills/error-messages, .github/skills/error-messages and .opencode/skills/error-messages in your project.

What does Error Messages need to run?

SKILL.md names no scripts, command-line tools or credentials: Error Messages is instructions for the agent only. Our summary lists: Node.js.

Does Error Messages access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Error Messages safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Error Messages use?

Error Messages is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Error Messages use?

About 2.3k tokens (SKILL.md is roughly 9.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Error Messages?

Skills that share tags, products or a category with Error Messages: Contributor-First PR Merge (HKUDS/OpenHarness, 16k stars), Create Pull Request (cline/cline, 70k stars), Pull Request Title and Body Writer (openinterpreter/openinterpreter, 69k stars) and Draft Release Notes (jamiepine/voicebox, 57k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Error Messages?

github (a GitHub organization, an official publisher) maintains it in github/gh-aw, which has 5,350 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on October 7, 2026.

Source: github/gh-aw on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.