Skip to content

Improve actionable CLI error messages - #52175

Closed
pelikhan with Copilot wants to merge 4 commits into
mainfrom
copilot/squad-plan-fix-error-messages
Closed

Improve actionable CLI error messages#52175
pelikhan with Copilot wants to merge 4 commits into
mainfrom
copilot/squad-plan-fix-error-messages

Conversation

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Updates low-compliance CLI validation errors in five scoped files to consistently state the invalid condition, expected input, and a concrete recovery example.

  • Organization runner

    • Clarifies required callback configuration and CI confirmation requirements.
  • Interactive workflows

    • Makes non-interactive environment and selection errors actionable.
    • Extends existing coverage for interactive-environment guidance.
  • Audit diff

    • Adds valid run-ID, distinct-comparison, duplicate-ID, and repository-format examples.
  • Workflow resolution

    • Clarifies missing workflow input, current-repository sources, and private workflow constraints.
  • Interactive add orchestration

    • Adds remediation guidance for missing resolved workflow specifications and names.
return fmt.Errorf(
    "repository %q is not in owner/repo format. Expected an owner and repository name separated by '/'. Example: --repo github/gh-aw",
    repoFlag,
)

run: https://github.com/github/gh-aw/actions/runs/31547117706> Generated by 👨‍🍳 PR Sous Chef · gpt54 · 7.19 AIC · ⌖ 5.2 AIC · ⊞ 8.5K ·

Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.5 AIC · ⌖ 9.23 AIC · ⊞ 8.5K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix error message compliance in five files Improve actionable CLI error messages Aug 11, 2026
Copilot AI requested a review from pelikhan August 11, 2026 23:23
@pelikhan
pelikhan marked this pull request as ready for review August 11, 2026 23:29
Copilot AI balanced review requested due to automatic review settings August 11, 2026 23:29
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Reviewed PR #52175 for over-engineering per Ponytail skill. This diff only rewords existing error strings (adding 'Expected...Example:' context) — no new abstractions, functions, dependencies, or structural complexity introduced. Lean already. Ship.

Generated by Ponytail Reviewer for #52175

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.individual.githubcopilot.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.individual.githubcopilot.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #52175 does not have the 'implementation' label and has only 29 new lines of code in business logic directories (threshold: 100).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions github-actions Bot mentioned this pull request Aug 11, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Improve actionable CLI error messages

The changes consistently apply the <What happened>. Expected <what was expected>. Example: <concrete example> pattern across CLI error messages. This is a clear, user-friendly improvement. The test updates in interactive_test.go correctly validate the new pattern.

One non-blocking suggestion left inline on org_runner.go.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 24.7 AIC · ⌖ 6.25 AIC · ⊞ 5.4K

Comment thread pkg/cli/org_runner.go
@@ -146,19 +146,19 @@ func runCommandForOrg(ctx context.Context, org string, repoGlobs []string, cbs o
return errors.New("createPR and createIssue are mutually exclusive")
}
if cbs.SearchFn == nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These callback validation errors are internal programming errors (not user-facing CLI messages). The new Example: values expose raw Go struct literal syntax (orgRunCallbacks{SearchFn: searchFn}) which is not actionable to CLI users.

Consider either omitting Example: for developer-facing internal errors, or replacing with a user-meaningful CLI example (e.g., gh aw run --org octo-org).

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the org callback examples are now developer-oriented and no longer expose raw Go struct literal syntax.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Summary

Score: ✅ Excellent (100/100)

This PR improves error message actionability. The test modification adds focused assertions to verify that error messages include actionable guidance ("Expected an interactive terminal", "Example: unset CI"), not just problem statements.

Analysis

Test Files Changed

  • pkg/cli/interactive_test.go (1 file modified)
    • ✅ Has required (go/redacted):build !integration tag
    • No new test functions (1 existing test modified)

Modified Test: TestCreateWorkflowInteractively_InAutomatedEnvironment

Aspect Rating Notes
Design Invariant behavioral_contract Error messages must include actionable guidance for CI environments
Value if Deleted high_value Regression: error messages could become less helpful
Coverage Type design_test Tests user-visible error message content
Assertions 3 error assertions All focus on error path and message clarity
Edge Cases Error path only Tests failure mode (CI environment)
Code Quality Excellent Setup/teardown with t.Cleanup(), clear failure messages

Changes in Detail

Lines 441-444 (unchanged context):
  - Asserts error is not nil
  - Checks for main error message

Lines 445-447 (NEW - added in this PR):
  + Verifies "Expected an interactive terminal" in error
  + Verifies "Example: unset CI" in error  
  + Ensures error message is actionable, not just descriptive

Why This Test Matters

This modification ensures the PR's goal of "actionable error messages" is actually tested. Without these assertions, the new error message strings could be mistakenly removed or truncated without detection. The test confirms:

  1. Problem clarity: Main error statement is present
  2. Actionable guidance: Users get clear direction ("Expected an interactive terminal")
  3. Concrete examples: Users see remediation ("Example: unset CI")

Scoring Breakdown

Component Points Reasoning
Design tests (40 pts) 40 100% of tests are design-focused (error message contract)
Edge cases (30 pts) 30 All assertions cover error path (non-happy path)
No duplication (20 pts) 20 No duplicate patterns detected
No inflation (10 pts) 10 3 lines added to test is proportional
Total 100

Verdict

APPROVED — Test quality is excellent. The PR adds focused, high-value assertions that verify the core design contract: error messages must be actionable, not just informative. No violations detected.


Infrastructure notes: No TestMain or goroutine-leak guards in this PR.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 13.5 AIC · ⌖ 3.14 AIC · ⊞ 7.6K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 100/100. All assertions verify actionable error message design contracts. 0% implementation tests (threshold: 30%). No violations.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /tdd, /codebase-design, and /grill-with-docs — requesting changes on three issues.

📋 Key Themes & Highlights

Issues

  • Thin test coverage: only interactive_test.go is updated; the other five changed files have no test assertions for the new error format
  • Internal API leaks Go syntax to users: org_runner.go examples show orgRunCallbacks{SearchFn: searchFn} — either make them developer-facing panics or replace with CLI examples
  • Embedded newline in error string: add_workflow_resolution.go line 411 breaks the single-line error convention and will cause issues in log aggregation and test assertions
  • Multi-select example is single-select: Example: 1 for comma-separated input is misleading

Positive Highlights

  • ✅ Consistent three-part pattern (condition → expected → example) applied uniformly
  • audit_diff_command.go and interactive.go errors are now genuinely actionable
  • ✅ The new test assertions in interactive_test.go are a good model for other files

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 39.7 AIC · ⌖ 6.82 AIC · ⊞ 7K
Comment /matt to run again

}
}

func TestCreateWorkflowInteractively_WithForceFlag(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] Test coverage is extended only for interactive.go — the five other changed files have no new or updated tests.

The structured error pattern (state, expected, example) is now enforced in one place but unverified in add_workflow_resolution.go, audit_diff_command.go, add_interactive_orchestrator.go, and org_runner.go. A regression in any of those files will go undetected.

💡 Suggested approach

Add a parallel assertion for each changed file that checks both an Expected and an Example: fragment:

if !strings.Contains(err.Error(), "Expected") || !strings.Contains(err.Error(), "Example:") {
    t.Errorf("Expected actionable error message, got %q", err.Error())
}

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: added focused assertions for the other changed validation paths, including org runner, audit diff, current-repository resolution, private workflow resolution, and add-wizard automation errors.

Comment thread pkg/cli/org_runner.go Outdated
}
if cbs.SearchFn == nil {
return errors.New("orgRunCallbacks.SearchFn is required")
return errors.New("organization search callback is not configured. Expected orgRunCallbacks.SearchFn to search organization repositories. Example: orgRunCallbacks{SearchFn: searchFn}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] The example text exposes internal Go struct syntax (orgRunCallbacks{SearchFn: searchFn}) to end users, but runCommandForOrg is an internal function — this error is only reachable by Go callers, not CLI users.

If this error is truly internal-only, the example should use Go call-site syntax. If it can surface to CLI users, the example should be a CLI command like the other files.

💡 Suggested fix

For an internal programming error, follow the same pattern as the existing createPR and createIssue are mutually exclusive message — keep it terse and developer-oriented, or use a panic:

return errors.New("orgRunCallbacks.SearchFn must not be nil")

For a user-facing error, use a CLI example consistent with every other changed file:

return errors.New("organization search callback is not configured. Expected orgRunCallbacks.SearchFn. Example: gh aw run --org octo-org")

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the internal org callback messages now use developer-oriented recovery text and avoid raw struct literal examples.

Comment thread pkg/cli/add_workflow_resolution.go Outdated
manifestPath := joinRepositoryPackagePath(spec.PackagePath, repositoryPackageManifestFileName)
return fmt.Errorf(
"invalid Agentic Workflow manifest %q: workflow %q sets private: true and cannot be included because private workflows cannot be added",
"agentic workflow manifest %q sets workflow %q to private: true. Expected an installable workflow with private: false. Example:\nprivate: false",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The error string contains a literal \n newline character, breaking from the single-line error convention used everywhere else in the file and across all other changed files.

Embedded newlines in error values complicate log aggregation, JSON marshalling, and string comparison in tests.

💡 Suggested fix

Keep the example on one line, consistent with all other changed errors:

"agentic workflow manifest %q sets workflow %q to private: true. Expected an installable workflow with private: false. Example: private: false",

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the private workflow guidance is now single-line and preserves the existing workflow-first diagnostic.

Comment thread pkg/cli/interactive.go
if idx, err := strconv.Atoi(input); err == nil {
if idx < 1 || idx > len(options) {
return "", fmt.Errorf("selection out of range (must be 1-%d)", len(options))
return "", fmt.Errorf("selection is out of range. Expected a number from 1 to %d. Example: 1", len(options))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The Example: 1 hint is not contextual — the actual valid range varies per call, but the example always shows 1. This is fine for the single-select path, but the multi-select path (promptNonInteractiveMultiSelect) allows comma-separated values; the example should reflect that.

💡 Suggested fix

For the multi-select error at line ~456 and ~475, a comma-separated example would be more instructive:

return nil, fmt.Errorf("selection %d is out of range. Expected a number from 1 to %d. Example: 1,2", idx, len(options))

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: multi-select range and unknown-value errors now use comma-separated examples (1,2).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves CLI validation errors with expected inputs and recovery examples.

Changes:

  • Expands error guidance across five CLI workflows.
  • Adds interactive-environment message assertions.
  • Clarifies audit and workflow-resolution validation failures.
Show a summary per file
File Description
pkg/cli/org_runner.go Improves organization-runner errors.
pkg/cli/interactive.go Improves interactive selection guidance.
pkg/cli/interactive_test.go Tests automated-environment guidance.
pkg/cli/audit_diff_command.go Adds actionable audit validation errors.
pkg/cli/add_workflow_resolution.go Improves workflow-resolution errors.
pkg/cli/add_interactive_orchestrator.go Improves interactive-add errors.

Review details

Suppressed comments (1)

pkg/cli/interactive.go:475

  • The prompt displays opt.label, but this parser accepts opt.value, so “displayed option name” is inaccurate whenever labels and values differ. Point users to an option value or the displayed numeric index.
		return nil, fmt.Errorf("option %q is not available. Expected a displayed option name or number. Example: 1", tok)
  • Files reviewed: 6/6 changed files
  • Comments generated: 6
  • Review effort level: Balanced

Comment thread pkg/cli/org_runner.go Outdated
}
if (createPR || createIssue) && !cbs.AutoYes && isRunningInCIFn() {
return errors.New("confirmation is required for --org create operations in CI; re-run with --yes to auto-accept")
return errors.New("organization create operations in CI need confirmation. Expected --yes to auto-accept in non-interactive environments. Example: gh aw run --org octo-org --yes")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the CI confirmation example now uses a valid org update create operation with --yes.

Comment thread pkg/cli/interactive.go Outdated
// IsRunningInCI centralizes the broader CI environment detection logic.
if envutil.GetBoolFromEnv("GO_TEST_MODE", false, interactiveLog) || IsRunningInCI() {
return errors.New("interactive workflow creation cannot be used in automated tests or CI environments")
return errors.New("interactive workflow creation is unavailable in automated tests or CI environments. Expected an interactive terminal. Example: unset CI and run the command from a terminal")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the interactive workflow recovery now points to running gh aw new from a local terminal outside automation, and the test assertion was updated.

Comment thread pkg/cli/interactive.go Outdated
}
}
return "", fmt.Errorf("invalid selection %q", input)
return "", fmt.Errorf("selection %q is not available. Expected a displayed option name or number. Example: 1", input)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: non-interactive selection errors now describe accepted option values rather than displayed labels.

Comment thread pkg/cli/add_workflow_resolution.go Outdated
}
if spec.RepoSlug == currentRepoSlug {
return fmt.Errorf("cannot add workflows from the current repository (%s). The 'add' command is for installing workflows from other repositories", currentRepoSlug)
return fmt.Errorf("workflow source %q is the current repository. Expected a workflow from another repository. Example: gh aw add github/gh-aw/example-workflow", currentRepoSlug)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: restored the current-repository diagnostic identity and changed the example to an unambiguously different repository.

Comment thread pkg/cli/add_workflow_resolution.go Outdated
manifestPath := joinRepositoryPackagePath(spec.PackagePath, repositoryPackageManifestFileName)
return fmt.Errorf(
"invalid Agentic Workflow manifest %q: workflow %q sets private: true and cannot be included because private workflows cannot be added",
"agentic workflow manifest %q sets workflow %q to private: true. Expected an installable workflow with private: false. Example:\nprivate: false",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: restored the workflow-first sets private: true diagnostic and kept the actionable guidance on one line.

Comment thread pkg/cli/add_interactive_orchestrator.go Outdated
// IsRunningInCI centralizes the broader CI environment detection logic.
if envutil.GetBoolFromEnv("GO_TEST_MODE", false, addInteractiveLog) || IsRunningInCI() {
return errors.New("interactive add cannot be used in automated tests or CI environments")
return errors.New("interactive add is unavailable in automated tests or CI environments. Expected an interactive terminal. Example: unset CI and run the command from a terminal")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61891c4e78: the add-wizard recovery now points to running gh aw add-wizard from a local terminal outside automation.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please address the open review threads below, fix the failed checks, refresh the branch if needed, and run the pr-finisher skill.

Open review threads (newest first):...

Addressed in 61891c4e78: fixed the open review-thread issues, restored the failing private-workflow diagnostic substring, added focused coverage for the actionable errors, and fixed the related staticcheck failure. Local validation passed (make fmt, make lint, make test-unit, make test, make recompile, make agent-report-progress).

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Triage: PR #52175

Generated by 🔧 PR Triage Agent · auto · 44.5 AIC · ⌖ 2.66 AIC · ⊞ 7.8K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please finish the remaining review cleanup below, refresh the branch if GitHub offers it, and run the pr-finisher skill.

Open review threads (newest first):

The PR author replied, but these threads still appear unresolved. Please resolve the outstanding reviewer concerns or explicitly close the threads as appropriate.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.5 AIC · ⌖ 9.23 AIC · ⊞ 8.5K ·
Comment /souschef to run again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

4 participants