From c287342f95d77414f4ab8a7c94d1c560bd7a1d52 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 22:31:11 +0000 Subject: [PATCH 1/3] Initial plan From c905a544497681f1faf7b3917f3db9804324b987 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 22:36:58 +0000 Subject: [PATCH 2/3] Add config.FormatConfigError helper using ParseError.ErrorWithUsage() --- internal/cmd/root.go | 2 +- internal/config/config_core.go | 20 ++++++++++++++++++++ internal/config/config_core_test.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 6bc2d819d..719e00127 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -215,7 +215,7 @@ func run(cmd *cobra.Command, args []string) error { if err != nil { // Log configuration validation errors to markdown logger - logger.LogErrorToMarkdown("startup", "Configuration validation failed:\n%s", err.Error()) + logger.LogErrorToMarkdown("startup", "Configuration validation failed:\n%s", config.FormatConfigError(err)) return fmt.Errorf("failed to load config: %w", err) } diff --git a/internal/config/config_core.go b/internal/config/config_core.go index 62ef9814d..309bf10a0 100644 --- a/internal/config/config_core.go +++ b/internal/config/config_core.go @@ -547,6 +547,26 @@ func LoadFromFile(path string) (*Config, error) { return &cfg, nil } +// FormatConfigError returns a rich diagnostic message for TOML parse errors. +// When err wraps a toml.ParseError, it returns ParseError.ErrorWithUsage() which +// includes a source-code snippet and column pointer, e.g.: +// +// toml: line 5 (field command): expected "=", got "[" instead +// +// 3 | [servers.github] +// 4 | command = "docker" +// 5 | [servers.github +// | ^ +// +// For all other error types, it falls back to err.Error(). +func FormatConfigError(err error) string { + var perr toml.ParseError + if errors.As(err, &perr) { + return perr.ErrorWithUsage() + } + return err.Error() +} + // logConfig is the debug logger for the config package. // Enable with DEBUG=config:* or DEBUG=*. var logConfig = logger.New("config:config") diff --git a/internal/config/config_core_test.go b/internal/config/config_core_test.go index 3e82dcddb..e0259b3ef 100644 --- a/internal/config/config_core_test.go +++ b/internal/config/config_core_test.go @@ -62,6 +62,35 @@ command = "docker" assert.Greater(t, perr.Position.Col, 0, "parse error should include column number") } +// TestFormatConfigError verifies that FormatConfigError returns source-context-rich +// output for toml.ParseError and falls back to err.Error() for other errors. +func TestFormatConfigError(t *testing.T) { + t.Run("wraps toml.ParseError with ErrorWithUsage", func(t *testing.T) { + // Write invalid TOML to trigger a ParseError + path := writeTempTOML(t, "[gateway]\nport 3000\n") + _, err := LoadFromFile(path) + require.Error(t, err, "expected error from invalid TOML") + + msg := FormatConfigError(err) + + // ErrorWithUsage output contains the file source snippet (|) and a + // column pointer (^), which Error() alone does not include. + assert.Contains(t, msg, "|", "ErrorWithUsage should include source-snippet lines") + assert.Contains(t, msg, "^", "ErrorWithUsage should include column pointer") + }) + + t.Run("falls back to err.Error() for non-TOML errors", func(t *testing.T) { + err := fmt.Errorf("some other error") + assert.Equal(t, "some other error", FormatConfigError(err)) + }) + + t.Run("falls back to err.Error() for wrapped non-TOML errors", func(t *testing.T) { + inner := fmt.Errorf("inner error") + err := fmt.Errorf("config error: %w", inner) + assert.Equal(t, "config error: inner error", FormatConfigError(err)) + }) +} + func TestLoadFromFile_BothTracingAndOpenTelemetry_OpenTelemetryTakesPrecedence(t *testing.T) { path := writeTempTOML(t, ` [gateway.tracing] From 79b9adb636fc931d2d05bb3e51ea2f06ed7190e9 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Thu, 2 Jul 2026 15:49:30 -0700 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/config/config_core.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/config/config_core.go b/internal/config/config_core.go index 309bf10a0..1ed0f8cb4 100644 --- a/internal/config/config_core.go +++ b/internal/config/config_core.go @@ -560,6 +560,9 @@ func LoadFromFile(path string) (*Config, error) { // // For all other error types, it falls back to err.Error(). func FormatConfigError(err error) string { + if err == nil { + return "" + } var perr toml.ParseError if errors.As(err, &perr) { return perr.ErrorWithUsage()