Skip to content

[plan] Add fuzzy matching for common user input errors #33317

@github-actions

Description

@github-actions

Objective

Implement "Did you mean?" fuzzy matching for engine names, MCP server names, and event types to help users quickly fix typos and misspellings.

Context

From discussion #33307: Users currently see unhelpful errors like "invalid engine: copiliot" when they make typos. The codebase already has excellent fuzzy matching in pkg/cli/run_workflow_validation.go that can be reused for other common error scenarios.

Approach

  1. Extract the fuzzy matching logic from pkg/cli/run_workflow_validation.go into a reusable utility function in pkg/stringutil/
  2. Apply fuzzy matching to these high-impact error scenarios:
    • Engine names (copilot, claude, codex, custom)
    • MCP server names (from registry or user-configured)
    • GitHub event types (push, pull_request, issues, etc.)
    • Permission scopes (contents, issues, pull_requests, etc.)

Files to Modify

  • Create: pkg/stringutil/fuzzy_match.go (extract from run_workflow_validation.go)
  • Create: pkg/stringutil/fuzzy_match_test.go (test coverage)
  • Update: pkg/workflow/engine_validation.go (add fuzzy matching for engine names)
  • Update: pkg/workflow/mcp_property_validation.go (add fuzzy matching for MCP servers)
  • Update: pkg/workflow/event_validation.go (add fuzzy matching for event types)
  • Update: pkg/workflow/permissions_validation.go (add fuzzy matching for permission scopes)

Example Implementation

Extracted utility function:

// pkg/stringutil/fuzzy_match.go
package stringutil

// FindClosestMatches returns suggestions for misspelled input
func FindClosestMatches(input string, validOptions []string, maxDistance int) []string {
    // Use Levenshtein distance or similar algorithm
    // Return top 3 closest matches if distance <= maxDistance
}

Usage in validation:

// Before
return fmt.Errorf("invalid engine: %s", engineName)

// After
validEngines := []string{"copilot", "claude", "codex", "custom"}
matches := stringutil.FindClosestMatches(engineName, validEngines, 2)
if len(matches) > 0 {
    return NewValidationError(
        "engine",
        engineName,
        fmt.Sprintf("engine '%s' is not valid", engineName),
        fmt.Sprintf("Did you mean '%s'?\n\nValid engines: %s", 
            strings.Join(matches, "', '"), 
            strings.Join(validEngines, ", "))
    )
}

Acceptance Criteria

  • Fuzzy matching utility function extracted to pkg/stringutil/fuzzy_match.go
  • Engine name validation suggests closest match when typo detected
  • MCP server validation suggests closest match when typo detected
  • Event type validation suggests closest match when typo detected
  • Permission scope validation suggests closest match when typo detected
  • All fuzzy matching logic has test coverage with common typo scenarios
  • Suggestions include valid options list for reference
  • Run make agent-finish successfully before committing

Testing Strategy

  1. Test common typos: "copiliot" → suggests "copilot"
  2. Test case sensitivity: "Copilot" → suggests "copilot"
  3. Test partial matches: "cop" → suggests "copilot"
  4. Test distance threshold: "xyz" → no suggestions (too different)
  5. Verify existing tests still pass

Reference

Generated by 📋 Plan Command · ● 12.7M ·

  • expires on May 21, 2026, 2:12 PM UTC

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions