Fix non-deterministic engine validation error message#14313
Conversation
- Add formatListWithOr helper function to format lists with "or" conjunction - Sort engine names before formatting error message for deterministic output - Update validateEngine to use sorted engines with proper "or" formatting - Update test to check for prefix match instead of exact match to allow "Did you mean" suggestions - Add comprehensive tests for formatListWithOr helper function Fixes issue where TestValidateEngine failed due to non-deterministic map iteration order when listing supported engines. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
🔍 PR Triage ResultsCategory: bug | Risk: low | Priority: 42/100 Scores Breakdown
📋 Recommended Action: batch_reviewThis test stability fix should be reviewed together with PRs #14312 and #14301 as part of the code quality improvements batch ( Batch Context: Group with other test fixes and code quality improvements for efficient review. Triaged by PR Triage Agent on 2026-02-07
|
There was a problem hiding this comment.
Pull request overview
This PR fixes intermittent failures in the cmd/gh-aw CLI integration tests by making the engine validation error message deterministic, eliminating nondeterministic Go map iteration ordering from user-facing output.
Changes:
- Sort supported engine IDs before rendering them in
validateEngineerror messages. - Add a
formatListWithOrhelper to produce grammatically correct lists (including Oxford comma). - Update
TestValidateEngineto assert using prefix matching so optional “Did you mean” suggestions don’t break the test.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cmd/gh-aw/main.go | Sorts engine list and uses formatListWithOr to build deterministic, readable validation errors. |
| cmd/gh-aw/main_entry_test.go | Changes the assertion to prefix-match the base error message to allow appended suggestions. |
| cmd/gh-aw/format_list_test.go | Adds unit tests for formatListWithOr list formatting behavior. |
Comments suppressed due to low confidence (1)
cmd/gh-aw/main.go:73
return fmt.Errorf("%s", errMsg)is equivalent to returningerrors.New(errMsg)(orfmt.Errorf("%s", ...)without adding value). Consider usingerrors.New(errMsg)to make it clear this is a static message and avoid the redundant formatting call.
errMsg := fmt.Sprintf("invalid engine value '%s'. Must be %s", engine, formattedList)
if len(suggestions) > 0 {
errMsg = fmt.Sprintf("invalid engine value '%s'. Must be %s.\n\nDid you mean: %s?",
engine, formattedList, suggestions[0])
}
return fmt.Errorf("%s", errMsg)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Check that error message contains the expected format | ||
| // Error may include "Did you mean" suggestions, so we check if it starts with the base message | ||
| expectedMsg := fmt.Sprintf("invalid engine value '%s'. Must be 'claude', 'codex', 'copilot', or 'custom'", tt.engine) | ||
| if tt.errMessage != "" && !strings.HasPrefix(err.Error(), expectedMsg) { | ||
| t.Errorf("validateEngine(%q) error message = %v, want to start with %v", tt.engine, err.Error(), expectedMsg) | ||
| } |
There was a problem hiding this comment.
tt.errMessage is no longer used to form the expected assertion (it only gates the check). This makes the table data misleading and harder to maintain. Consider either (a) removing errMessage from the test cases and keying off expectErr, or (b) using tt.errMessage to build the expected prefix (e.g., include the full base message there) so each case asserts what it declares.
TestValidateEnginewas failing intermittently because the error message format depended on Go map iteration order, which is non-deterministic. The test expected'claude', 'codex', 'copilot', or 'custom'but the actual output could be any permutation like'codex', 'copilot', 'custom', 'claude'.Changes
formatListWithOrhelper for proper grammatical conjunction (handles 0/1/2/3+ items with oxford comma)Result
Error messages now consistently display as:
The
formatListWithOrhelper can be reused for other CLI list formatting needs.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.