-
Notifications
You must be signed in to change notification settings - Fork 295
Description
π Error Message Quality Analysis
Analysis Date: 2026-03-13
Test Cases: 3
Average Score: 65.3/100
Status:
Executive Summary
Daily quality analysis of compiler error messages found one critical failure (YAML syntax errors score 46/100) and two acceptable results (engine typo 73/100, negative timeout 77/100). The average of 65.3/100 falls below the 70-point quality threshold.
The root issue is that YAML parse errors are wrapped by formatCompilerError using a hardcoded line 1, column 1 fallback, even though the actual error location is embedded in the goccy [line:col]: formatted string. This produces a misleading IDE link (file.md:1:1) while showing the real location only as internal goccy text β confusing both humans and tooling. Engine validation errors have the same line:1:1 problem, though their message content is excellent.
Key Findings:
- β
Strengths: Engine validation errors have "Did you mean?" suggestions, valid-values lists, and documentation links. Schema constraint errors (Test 3) have precise
file:line:collocation and source context with visual underline. β οΈ Weaknesses: YAML syntax errors expose raw goccy error format with YAML jargon.formatCompilerErroralways falls back toline:1:col:1, discarding positional info already available in the error text. No actionable fix suggestions for YAML errors.- β Critical Issue: YAML parse errors score 46/100 β below the critical threshold of 55. The combined
file:1:1: error: failed to parse frontmatter:\n[16:1]: mapping values are not allowed in this contextformat is inconsistent and misleading.
Test Case Results
Test Case 1: Invalid YAML Syntax β Score: 46/100 β POOR (below critical threshold 55)
Test Configuration
Workflow: smoke-gemini.md (79 lines β simple)
Error Type: Category A β Invalid YAML syntax
Error Introduced: Line 16: engine gemini (removed colon β engine: with indented id: gemini replaced by bare scalar engine gemini)
Compiler Output
/tmp/test-1.md:1:1: error: failed to parse frontmatter:
[16:1]: mapping values are not allowed in this context
15 | name: Smoke Gemini
> 16 | engine gemini
17 | strict: true
```
*(The `file:1:1:` IDE prefix is the `formatCompilerError` fallback; the real location `[16:1]` comes from `yaml.FormatError` embedded inside the message.)*
#### Code Path
1. `pkg/parser/frontmatter_content.go:64` β `yaml.Unmarshal` fails
2. `pkg/parser/yaml_error.go:29` β `yaml.FormatError(err, false, true)` formats with source context
3. Returns `"failed to parse frontmatter:\n[16:1]: mapping values are not allowed..."`
4. `pkg/workflow/compiler.go:84` β `formatCompilerError(markdownPath, "error", err.Error(), err)` wraps with `Line:1, Column:1`
5. `pkg/workflow/compiler_error_formatter.go:33` β `console.FormatError` produces `file:1:1: error: (multi-line YAML text)`
#### Evaluation Scores
| Dimension | Score | Notes |
|-----------|-------|-------|
| Clarity | 15/25 | "mapping values are not allowed in this context" is raw YAML jargon; `file:1:1` vs `[16:1]` creates confusion |
| Actionability | 10/25 | Source context is shown but no suggestion on what to change. No "Did you forget ':' after 'engine'?" |
| Context | 15/20 | Source lines with `>` pointer are present (via goccy), but IDE link points to wrong line (1 not 16) |
| Examples | 0/15 | No example of correct syntax |
| Consistency | 6/15 | Mixed formats: `file:1:1: error:` wrapping `[16:1]:` text. Other errors use `file:N:M:` correctly. |
| **Total** | **46/100** | **POOR β below critical threshold** |
#### Strengths
- β
Source code context is displayed with `>` pointer (thanks to `yaml.FormatError(..., true)`)
- β
The actual error line IS shown β just buried in the text
#### Weaknesses
- β `formatCompilerError` uses `Line:1, Column:1` fallback β IDE jumps to the wrong line
- β "mapping values are not allowed in this context" is YAML parser jargon, not plain English
- β No hint that the fix is simply adding `:` after the key name
- β No example of correct YAML syntax
- β `failed to parse frontmatter:` + `[16:1]:` + `file:1:1:` is three different location indicators, all inconsistent
#### Improvement Suggestions
1. **Parse `[line:col]` from `FormatYAMLError` output and use `formatCompilerErrorWithPosition`**:
```go
// In pkg/workflow/compiler.go (~line 77-84):
// Instead of formatCompilerError (line:1, col:1), extract line/col from FormatYAMLError
line, col := extractLineColFromYAMLError(err)
return formatCompilerErrorWithPosition(markdownPath, line, col, "error", err.Error(), err)
```
2. **Translate common YAML error messages** in `pkg/parser/yaml_error.go`:
```go
var yamlErrorTranslations = map[string]string{
"mapping values are not allowed in this context": "Expected 'key: value' β did you forget the ':' after the key?",
"did not find expected key": "Check indentation β unexpected content at this level",
}
```
3. **Add "Correct usage" hint** for YAML syntax errors:
```
/tmp/test-1.md:16:1: error: Expected 'key: value' format
> 16 | engine gemini
^^^
Hint: Did you forget ':' after 'engine'?
Correct usage: engine: copilot
```
</details>
<details>
<summary><b>Test Case 2: Invalid Engine Name</b> β Score: 73/100 β
Good</summary>
#### Test Configuration
**Workflow**: `dead-code-remover.md` (236 lines β medium)
**Error Type**: Category B β Invalid configuration value
**Error Introduced**: Line 11: `engine: copiilot` (extra `i` β typo for `copilot`)
#### Compiler Output
```
/tmp/test-2.md:1:1: error: invalid engine: copiilot. Valid engines are: claude, codex, copilot, gemini.
Did you mean: copilot?
Example:
engine: copilot
See: https://docs.github.com/en/enterprise-cloud@latest/actions/using-github-copilot/using-copilot-in-github-actions
```
#### Code Path
1. `pkg/parser/schema_validation.go` β schema passes (engine string type is unconstrained in JSON schema)
2. `pkg/workflow/compiler_orchestrator_engine.go:254` β `c.engineCatalog.Resolve("copiilot", ...)` fails
3. `pkg/workflow/engine_definition.go:264` β builds multi-line error with "Did you mean?" suggestion
4. Propagates to `pkg/workflow/compiler.go:84` β wrapped by `formatCompilerError` with `Line:1, Column:1`
#### Evaluation Scores
| Dimension | Score | Notes |
|-----------|-------|-------|
| Clarity | 21/25 | "invalid engine: copiilot" is clear. File path shown. `1:1` is slightly misleading. |
| Actionability | 23/25 | "Did you mean: copilot?", valid engines, example, docs link β excellent |
| Context | 7/20 | File path present but line points to 1 (wrong). No source context showing the `engine:` line. |
| Examples | 14/15 | `engine: copilot` example + documentation link |
| Consistency | 8/15 | `file:1:1:` format (wrong line). Test 3 gets precise location; engine errors do not. |
| **Total** | **73/100** | **Good** |
#### Strengths
- β
"Did you mean: copilot?" typo correction is excellent DX
- β
Lists all valid engines
- β
Shows `engine: copilot` usage example
- β
Links to documentation
- β
File path is present
#### Weaknesses
- β οΈ Line/column is `1:1` β IDE navigation points to top of file, not the `engine:` field
- β οΈ No source context (the `engine: copiilot` line is not shown)
#### Improvement Suggestions
1. **Surface the `engine:` line number via schema-level validation** or by using `formatCompilerErrorWithPosition` with a field-lookup step before returning the engine error.
2. **Add source context** β even a single-line context showing `engine: copiilot` would significantly improve the error.
</details>
<details>
<summary><b>Test Case 3: Negative Timeout Value</b> β Score: 77/100 β
Good</summary>
#### Test Configuration
**Workflow**: `code-simplifier.md` (406 lines β complex)
**Error Type**: Category C β Semantic/range error
**Error Introduced**: Line 14: `timeout-minutes: -10` (negative value, schema `minimum: 1`)
#### Compiler Output
```
/tmp/test-3.md:14:18: error: must be at least 1 (got -10)
12 |
13 | tracker-id: code-simplifier
> 14 | timeout-minutes: -10
~~~
15 |
16 | imports:
17 | - shared/reporting.md
```
#### Code Path
1. `pkg/parser/schema_validation.go` β `validateWithSchemaAndLocation` finds `minimum` constraint violation
2. `pkg/parser/schema_errors.go:26` β `translateSchemaConstraintMessage`: `"minimum: got -10, want 1"` β `"must be at least 1 (got -10)"`
3. `pkg/parser/schema_compiler.go:261` β `LocateJSONPathInYAMLWithAdditionalProperties` finds precise column
4. `pkg/parser/schema_compiler.go:305-318` β `console.FormatError` with precise `file:14:18`
#### Evaluation Scores
| Dimension | Score | Notes |
|-----------|-------|-------|
| Clarity | 22/25 | "must be at least 1 (got -10)" is very clear |
| Actionability | 17/25 | Clear what the constraint is, but no suggestion for a valid value |
| Context | 19/20 | Precise file:line:col, 7-line source window with `~~~` underline |
| Examples | 5/15 | No "e.g. timeout-minutes: 30" shown. Schema has `examples: [5, 10, 30]` but unused. |
| Consistency | 14/15 | Proper IDE-parseable format, consistent with other schema errors |
| **Total** | **77/100** | **Good** |
#### Strengths
- β
Precise `file:14:18:` β IDE navigation works correctly
- β
Source context with visual `~~~` underline at exact error column
- β
Plain-English constraint message ("must be at least 1")
- β
Shows the bad value in parentheses ("got -10")
#### Weaknesses
- β οΈ No example of valid value (schema has `examples: [5, 10, 30]` but they're not surfaced)
- β οΈ Message could add: `Hint: Valid values: 5, 10, 30 (see examples in schema)`
#### Improvement Suggestion
Surface schema `examples` in constraint errors:
```
/tmp/test-3.md:14:18: error: must be at least 1 (got -10)
> 14 | timeout-minutes: -10
~~~
Example: timeout-minutes: 30
Overall Statistics
| Metric | Value |
|---|---|
| Tests Run | 3 |
| Average Score | 65.3/100 |
| Excellent (85+) | 0 |
| Good (70-84) | 2 |
| Acceptable (55-69) | 0 |
| Poor (40-54) | 1 β critical |
| Critical (<40) | 0 |
Quality Assessment:
Priority Improvement Recommendations
π΄ High Priority β Fix YAML parse error location (pkg/workflow/compiler.go)
The formatCompilerError fallback at line 84 always uses Line:1, Column:1. For YAML parse errors, the actual line/column is already available in the error text produced by FormatYAMLError. The fix is to extract it and use formatCompilerErrorWithPosition:
// pkg/workflow/compiler.go ~line 77-84
if err := ...; err != nil {
if isAlreadyFormatted(err) {
return err
}
// NEW: extract line/col from YAML error instead of defaulting to 1:1
line, col := parser.ExtractLineColFromYAMLError(err)
if line > 0 {
return formatCompilerErrorWithPosition(markdownPath, line, col, "error", err.Error(), err)
}
return formatCompilerError(markdownPath, "error", err.Error(), err)
}Impact: Fixes IDE navigation for ALL YAML syntax errors (not just this test case).
π΄ High Priority β Translate YAML error jargon (pkg/parser/yaml_error.go)
The goccy YAML parser produces technical messages like "mapping values are not allowed in this context". These should be translated to plain English:
// pkg/parser/yaml_error.go
var yamlJargonTranslations = map[string]string{
"mapping values are not allowed in this context": "unexpected value β check that all keys use 'key: value' format",
"did not find expected key": "unexpected content β check indentation",
"found character that cannot start any token": "invalid character in YAML β check for special characters",
"could not find expected ':'": "missing ':' β all keys require a colon after them",
}π‘ Medium Priority β Add source context to engine validation errors (pkg/workflow/engine_definition.go)
Engine validation errors currently show file:1:1: with no source context. Since the engine field location is known (it's a top-level YAML key), the error should include the engine: line:
// Currently (engine_definition.go:258):
errMsg := fmt.Sprintf("invalid engine: %s. Valid engines are: %s.\n\nDid you mean: %s?...", ...)
return nil, fmt.Errorf("%s", errMsg)
// Better: return a structured error that includes location info,
// OR catch this at schema validation time in validateEngineSpecificRules()
// where file location is already available
```
Alternatively, restore engine enum validation in the JSON schema (`engine_config` string variant) so it's caught by `validateWithSchemaAndLocation` which already provides precise location.
#### π’ Low Priority β Surface schema `examples` in constraint errors
For `minimum`/`maximum` violations, append schema examples from the field definition:
```
/tmp/test-3.md:14:18: error: must be at least 1 (got -10)
> 14 | timeout-minutes: -10
Example: timeout-minutes: 30Implementation Guide
Key Files to Modify
| File | Change |
|---|---|
pkg/workflow/compiler.go |
Extract YAML error line/col before calling formatCompilerError |
pkg/parser/yaml_error.go |
Add yamlJargonTranslations map, apply in FormatYAMLError |
pkg/workflow/engine_definition.go |
Propagate location info OR add engine enum to schema |
pkg/parser/schema_errors.go |
Surface schema field examples in constraint messages |
Suggested Unit Tests
// pkg/workflow/compiler_test.go
func TestYAMLSyntaxErrorHasCorrectLineNumber(t *testing.T) {
// engine gemini (missing colon) should produce error at line 16, not line 1
}
// pkg/workflow/engine_definition_test.go
func TestEngineValidationErrorHasFileLocation(t *testing.T) {
// invalid engine should show the engine: field line, not line 1
}References:
Generated by Daily Syntax Error Quality Check Β· β·
- expires on Mar 16, 2026, 6:15 PM UTC