[sergo] Sergo Report: Error Patterns Analysis - 2026-03-29 #23480
Closed
Replies: 1 comment
-
|
This discussion has been marked as outdated by Sergo - Serena Go Expert. A newer discussion is available at Discussion #23504. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Executive Summary
Today's Sergo analysis focused on error handling patterns in the
gh-awGo codebase (629 non-test.gofiles, ~149K LOC). Using Serena's LSP-powered semantic search and pattern matching, three actionable issues were found, with the most impactful being timestamps embedded in validation error strings — a pattern that affects 35+ call sites and can cause test non-determinism. Two additional medium-priority issues were identified: idiomatic misuse offmt.Errorf("%s", ...)(12+ locations) and silently discardedos.Setenverrors in secret-handling code.This was the first Sergo run on this repository, establishing a baseline for future analysis.
🛠️ Serena Tools Update
Tools Snapshot
Tool Capabilities Used Today
activate_projectget_symbols_overviewfind_symbolConvertToInt,NewValidationErrorbodiesfind_referencing_symbolsNewValidationErrorcall sitessearch_for_patternfmt.Errorf("%s",...),_ = os.Setenv,panic(,context.Background()patterns📊 Strategy Selection
Cached Reuse Component (50%)
No prior cache — this run establishes the baseline. The "reuse" component was fulfilled by using well-known Go static analysis heuristics (error handling anti-patterns, ignored errors, panic in init code) that consistently yield high-value findings in Go codebases.
New Exploration Component (50%)
Novel approach: Deep structural inspection of the error type hierarchy using Serena's symbol overview and referencing tools. Rather than just pattern-searching for strings, this explored the architecture of error types to find design-level issues (missing
Unwrap(), timestamp coupling, inconsistency across error structs).Combined Strategy Rationale
Pattern search (broad) + symbol navigation (deep) is a complementary pairing: patterns surface the volume of an issue across the codebase, while symbol navigation reveals why the pattern is problematic and how widely it's used.
🔍 Analysis Execution
Codebase Context
pkg/workflow,pkg/cli,pkg/semverutil,pkg/parserpkg/workflow/workflow_errors.go,pkg/cli/engine_secrets.go, error pattern sitesFindings Summary
📋 Detailed Findings
High Priority
Finding 1: Timestamps embedded in error message strings
WorkflowValidationError,OperationError, andConfigurationErrorinpkg/workflow/workflow_errors.goall embedtime.Now()RFC3339 timestamps directly in theirError()string output:This pattern is repeated for all three error types (lines 43–44, ~91, 145–146). The timestamp is computed at construction time via
time.Now()and baked into the error string.Impact:
NewValidationErrorhas 35+ call sites acrosspkg/workflow/safe_outputs_validation.go,expression_syntax_validation.go,sandbox_validation.go,npm_validation.go, and many othersMedium Priority
Finding 2:
fmt.Errorf("%s", ...)used instead oferrors.New()12+ locations use
fmt.Errorf("%s", someString)to construct errors from already-formatted strings. This is semantically misleading — it looks like error wrapping (which uses%w) but isn't. The correct idiomatic form iserrors.New(someString).Locations include:
pkg/workflow/workflow_errors.go:266pkg/workflow/template_injection_validation.go:305pkg/workflow/dangerous_permissions_validation.go:96pkg/workflow/permissions_validation.go:346pkg/workflow/engine_validation.go:79pkg/workflow/runtime_validation.go:91pkg/workflow/tools_validation.go:349pkg/workflow/frontmatter_error.go:80pkg/cli/run_workflow_validation.go:269pkg/cli/run_workflow_execution.go:210pkg/parser/import_error.go:68,117pkg/workflow/engine_definition.go:280Example pattern
The
fmt.Errorf("%s", ...)form also triggers thegovetlinter'sprintfchecker in some configurations, since%wis the expected verb for wrapping.Low Priority
Finding 3: Silently discarded
os.Setenvreturn values in secret handlingIn
pkg/cli/engine_secrets.go, three calls toos.Setenv()discard the error:On Linux,
os.Setenvrarely fails, but if it does (e.g., if the environment variable name contains=), the secret won't be set in the process environment. The calling code then proceeds to upload the secret to the repository without validating that the local env was updated. A log warning at minimum would make failures debuggable.Context
These are in
promptForCopilotTokenUnified,promptForSystemTokenUnified, andpromptForGenericAPIKeyUnified. Each function prompts the user for a secret via a TUI form, then callsos.Setenvto store it locally before optionally uploading it. The discarded error means a rare OS-level failure would cause a silent, hard-to-diagnose bug.✅ Improvement Tasks Generated
Task 1: Remove timestamps from error message strings
Issue Type: Error Type Design
Problem:
WorkflowValidationError,OperationError, andConfigurationErrorembed RFC3339 timestamps in theirError()string output. Timestamps in error messages (not structured fields) break test determinism, prevent log deduplication, and add noise to user-facing output. The timestamp field is useful for structured logging — it should be kept as a field but not included in theError()string.Location(s):
pkg/workflow/workflow_errors.go:43-44—WorkflowValidationError.Error()pkg/workflow/workflow_errors.go:90-91—OperationError.Error()pkg/workflow/workflow_errors.go:145-146—ConfigurationError.Error()Impact:
Recommendation:
Remove the timestamp prefix from each
Error()method. Retain theTimestampfield for structured logging or metrics use.Before (
WorkflowValidationError.Error()):After:
Validation:
go test ./pkg/workflow/...— look for newly-passing tests that previously required time-insensitive matchingstrings.Contains(err.Error(), "[20to find assertions that relied on the timestamp prefixOperationErrorandConfigurationErrorEstimated Effort: Small
Task 2: Replace
fmt.Errorf("%s", ...)witherrors.New()Issue Type: Code Idiom / Linting
Problem:
12+ call sites use
fmt.Errorf("%s", someString)to construct new errors from formatted strings. This is:fmt.Errorfwith%wis for wrapping;%sdoes not wrapfmtformatting overhead)go vet/staticcheckin stricter configurationsLocation(s):
pkg/workflow/workflow_errors.go:266pkg/workflow/template_injection_validation.go:305pkg/workflow/dangerous_permissions_validation.go:96pkg/workflow/permissions_validation.go:346pkg/workflow/engine_validation.go:79pkg/workflow/runtime_validation.go:91pkg/workflow/tools_validation.go:349pkg/workflow/frontmatter_error.go:80pkg/cli/run_workflow_validation.go:269pkg/cli/run_workflow_execution.go:210pkg/parser/import_error.go:68,117pkg/workflow/engine_definition.go:280Impact:
Recommendation:
Replace each
fmt.Errorf("%s", expr)witherrors.New(expr). Ensureerrorsis imported in files where it isn't already.Before:
After:
Validation:
go build ./...to confirm no breakagego test ./...go vet ./...Estimated Effort: Small (mechanical replacement)
Task 3: Log or return
os.Setenverrors in secret-handling codeIssue Type: Error Handling / Silent Failure
Problem:
Three calls to
os.Setenvinpkg/cli/engine_secrets.go(lines 329, 377, 430) silently discard errors. If the environment variable cannot be set (e.g., due to a name containing=or an OS restriction), the secret will appear to be stored but won't be accessible to subsequent code that reads it from the environment.Location(s):
pkg/cli/engine_secrets.go:329—promptForCopilotTokenUnifiedpkg/cli/engine_secrets.go:377—promptForSystemTokenUnifiedpkg/cli/engine_secrets.go:430—promptForGenericAPIKeyUnifiedImpact:
Recommendation:
Log a warning (or return an error) if
os.Setenvfails. Given that these functions already print status messages to stderr, a warning log is appropriate:Before:
After:
Validation:
go build ./pkg/cli/...go test ./pkg/cli/...Estimated Effort: Small
📈 Success Metrics
This Run
Reasoning for Score
pkg/workflowandpkg/cliwell;pkg/parser, utility packages had less depth.📊 Historical Context
Cumulative Statistics
🎯 Recommendations
Immediate Actions
workflow_errors.gofmt.Errorf("%s", ...)witherrors.New()— mechanical replacement across 12 files; zero behavioral changeos.Setenvfailures — single-file change inengine_secrets.goLong-term Improvements
go vetorstaticcheckrule to the CI pipeline to catchfmt.Errorf("%s", ...)in futureWorkflowValidationErrorandConfigurationErrortypes currently lackUnwrap()methods (unlikeOperationError). If these errors are ever wrapped and then inspected witherrors.As(), addUnwrap()for consistency🔄 Next Run Preview
Suggested Focus Areas
find_symbolwith kind=Interface to enumerate interfaces and verify implementationscontext.Background()calls inpkg/cli(e.g.,resources.go:79,add_command.go:363) may be ignoring request contexts passed from callers — worth a focused passStrategy Evolution
Next run should reuse today's error-patterns approach (now cached) and pair it with a new interface-compliance exploration strategy.
References:
Beta Was this translation helpful? Give feedback.
All reactions