feat: add file/line context to validation errors#33466
Conversation
- Add FieldLocation struct with File, Line, Column fields - Add File, Line, Column fields to WorkflowValidationError - Add NewValidationErrorWithLocation constructor - Update WorkflowValidationError.Error() to omit timestamp when Line>0 (cleaner output when compiler adds file:line:col: prefix) - Update formatCompilerError to use location from WorkflowValidationError when Line>0, enabling precise IDE-navigable file:line:col: positions - Add FieldLines map[string]int to FrontmatterResult to track absolute line numbers of top-level frontmatter keys - Add extractTopLevelFieldLines helper that scans YAML text for key positions - Add FrontmatterFieldLines to WorkflowData for use by validation functions - Populate FrontmatterFieldLines in buildInitialWorkflowData - Add tests for all new functionality Agent-Logs-Url: https://github.com/github/gh-aw/sessions/16e4519d-23d2-443f-bb46-fbbdbe64519e Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
…hars Add a comment explaining why brackets and quotes are excluded from YAML key names in extractTopLevelFieldLines. These characters indicate non-standard key forms (inline maps, quoted keys) not used in workflow frontmatter. Also exclude quote characters to be safe. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/16e4519d-23d2-443f-bb46-fbbdbe64519e Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds infrastructure to attach source file/line/column context to workflow validation errors so compiler-style diagnostics can point IDEs at the offending frontmatter field.
Changes:
- Introduces location fields (
File,Line,Column) forWorkflowValidationErrorplus aNewValidationErrorWithLocationconstructor, and updatesError()formatting to omit timestamps when a line is present. - Updates
formatCompilerErrorto promotefile/line/colfrom a*WorkflowValidationErrorcause instead of always defaulting to1:1. - Extends frontmatter parsing to compute absolute line numbers for top-level YAML keys and plumbs them into
WorkflowData, with new parser tests.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/workflow_errors.go | Adds location support to validation errors and a new constructor; adjusts error string formatting. |
| pkg/workflow/compiler_error_formatter.go | Promotes file:line:col from *WorkflowValidationError when formatting compiler errors. |
| pkg/parser/frontmatter_content.go | Adds FieldLines to frontmatter parse results and implements top-level key line scanning. |
| pkg/parser/frontmatter_field_lines_test.go | Adds unit tests for extracting top-level frontmatter key line numbers. |
| pkg/workflow/compiler_types.go | Adds FrontmatterFieldLines to WorkflowData to carry parser-derived line info. |
| pkg/workflow/workflow_builder.go | Plumbs FieldLines from the parser into WorkflowData. |
| pkg/workflow/error_helpers_test.go | Adds tests for the new location-aware validation error constructor and formatting. |
| pkg/workflow/compiler_error_formatting_test.go | Adds tests to ensure compiler formatting uses location from validation errors. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 8/8 changed files
- Comments generated: 4
| // filePath: the file path to include in the error (typically markdownPath or lockFile) | ||
| // errType: the error type ("error" or "warning") | ||
| // message: the error message text | ||
| // cause: optional underlying error to wrap (use nil for validation errors) |
| FrontmatterName string // name field from frontmatter (for code scanning alert driver default) | ||
| FrontmatterEmoji string // emoji field from frontmatter (for display in footers and UI) | ||
| FrontmatterYAML string // raw frontmatter YAML content (rendered as comment in lock file for reference) | ||
| FrontmatterHash string // SHA-256 hash of frontmatter (computed before job building, used to derive stable heredoc delimiters) | ||
| FrontmatterFieldLines map[string]int // absolute 1-based line numbers of top-level frontmatter keys in the source file (populated by parser) | ||
| RawMarkdown string // raw markdown body before include expansion, used for frontmatter hash computation without re-reading the file |
| assert.Contains(t, msg, "Reason: not a valid engine") | ||
| assert.Contains(t, msg, "Suggestion: Did you mean 'copilot'?") | ||
| // No timestamp prefix when location is set | ||
| assert.NotContains(t, msg, "[20") |
| assert.Contains(t, errStr, "workflow.md", "Should contain file path") | ||
| assert.Contains(t, errStr, "15", "Should use the line number from WorkflowValidationError") | ||
| assert.Contains(t, errStr, "3", "Should use the column number from WorkflowValidationError") | ||
| // Should NOT default to 1:1 when location is known | ||
| assert.NotContains(t, errStr, "1:1", "Should not fall back to 1:1 when location is set") |
|
Hey
The technical quality is excellent — the feature adds valuable IDE-friendly error positioning, includes comprehensive tests, and maintains focus. If this PR was created as part of an approved workflow or by a core team member, please link the related issue or confirm the authorization. If you're a community contributor and this was created before discussion, consider: Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "patchdiff.githubusercontent.com"See Network Configuration for more information.
|
|
✅ PR Code Quality Reviewer completed the code quality review. |
|
🧪 Test Quality Sentinel completed test quality analysis. |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
There was a problem hiding this comment.
Review Summary
This PR adds IDE-navigable source locations to validation errors — a valuable UX improvement that will help users quickly jump to problematic fields in their workflow files.
✅ Strengths:
- Comprehensive test coverage with well-chosen edge cases
- Thoughtful UX decisions (e.g., omitting timestamps when location is known)
- Clean error wrapping using
errors.Asto extract validation error details - Good documentation of function behavior
💡 Minor Suggestions:
I've left two non-blocking comments about code clarity:
- The line counting increment pattern could be slightly more obvious
- The filePath override behavior should be documented in the function comment
Both suggestions are about maintainability and clarity for future readers rather than correctness issues.
Overall: The implementation is solid and ready to merge after addressing the minor documentation gap if desired.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
proxy.golang.org
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:
network:
allowed:
- defaults
- "proxy.golang.org"See Network Configuration for more information.
Note
🔒 Integrity filter blocked 1 item
The following item was blocked because it doesn't meet the GitHub integrity level.
- #33466
pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none🔎 Code quality review by PR Code Quality Reviewer · ● 5.9M
| // directly as file:line positions for IDE-navigable error messages. | ||
| func extractTopLevelFieldLines(yamlContent string, frontmatterStart int) map[string]int { | ||
| fieldLines := make(map[string]int) | ||
| relLine := 0 |
There was a problem hiding this comment.
Minor: Line counting pattern could be clearer
The increment-first pattern works correctly but is subtle:
relLine := 0
for line := range strings.SplitSeq(yamlContent, "\n") {
relLine++ // First iteration: relLine becomes 1 ✓Consider starting at 1 and incrementing at the end for clarity:
relLine := 1
for line := range strings.SplitSeq(yamlContent, "\n") {
// ... process line ...
relLine++
}This makes the 1-based indexing more obvious to future readers. The current code is correct, just less immediately clear.
| } | ||
| if vErr.File != "" { | ||
| filePath = vErr.File | ||
| } |
There was a problem hiding this comment.
Documentation gap: filePath parameter can be overridden
This code silently overrides the filePath parameter when the validation error has its own file:
if vErr.File != "" {
filePath = vErr.File
}While the tests confirm this is intentional behavior ("uses file from validation error when different from filePath"), the function documentation doesn't mention this override.
Suggestion: Update the function comment to note that when cause is a *WorkflowValidationError with a non-empty File field, that file path takes precedence over the filePath parameter. This prevents confusion for future callers.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd (test coverage analysis) and /zoom-out (architectural fit) based on this feature addition.
Key Themes
1. Fragile YAML parsing approach
The string-based line extraction logic in extractTopLevelFieldLines is brittle and doesn't leverage the YAML parser's built-in position tracking. The goccy/go-yaml library already provides AST nodes with line/column metadata — using that would be more robust and handle all YAML edge cases correctly.
2. Missing integration test
While unit tests cover individual components well, there's no end-to-end test proving that a validation error in a real workflow markdown file produces an IDE-navigable error message with file:line:col: prefix. This is the critical user-facing behavior.
3. Top-level fields only
The current implementation only tracks top-level frontmatter keys (e.g., engine, tools). Nested field validation errors (e.g., tools.github.toolsets) won't get location data, which limits the feature's usefulness since most validation errors are in nested config.
4. Test coverage gaps
The YAML parsing tests don't cover quoted keys, multiline block scalars, anchors/aliases, or flow collections — all valid YAML syntax that could appear in workflow frontmatter.
Positive Highlights
✅ Clean architectural separation — Parser extracts locations, error types hold them, compiler formatter uses them. Good layering.
✅ Backward compatible — The existing NewValidationError() constructor still works; new code can opt into locations.
✅ Well-structured tests — Table-driven test approach in frontmatter_field_lines_test.go is exemplary.
✅ Good documentation — Function comments clearly explain the line number calculations and edge cases.
Verdict
Requesting changes primarily on:
- YAML parsing robustness — Consider AST-based approach or add comprehensive edge case tests
- Integration testing — Add at least one end-to-end test of the error flow
- Documentation — Document the top-level-only limitation in
FieldLocationstruct
The core idea is solid and the implementation is clean, but the YAML parsing brittleness and missing integration test are blockers for production reliability.
Matt Pocock Skills Reference:
/tddskill — Red-green-refactor, test-first development/zoom-outskill — Architectural context and broader perspective
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 5.2M
| FrontmatterStart int // Line number where frontmatter starts (1-based) | ||
| FieldLines map[string]int // Absolute line numbers (1-based) of top-level frontmatter keys in the file | ||
| } | ||
|
|
There was a problem hiding this comment.
[/tdd] The YAML parsing logic in extractTopLevelFieldLines is fragile and lacks edge case coverage. Consider testing:
- Quoted keys:
"engine": copilotor'engine': copilot - Multiline values: Keys with
|or>block scalars - Anchors/aliases:
&anchorand*aliassyntax - Flow collections:
tools: {github: {toolsets: default}}
Without these tests, the parser may silently fail on valid YAML, causing location data to be missing when users need it most.
{
name: "quoted keys are skipped",
yamlContent: `"engine": copilot`,
frontmatterStart: 2,
wantFieldLines: map[string]int{}, // Currently excluded by containsAny check
},
{
name: "multiline block scalar",
yamlContent: `description: |
Line one
Line two
on: push`,
frontmatterStart: 2,
wantFieldLines: map[string]int{"description": 2, "on": 5},
},| // number of the first frontmatter content line (i.e. the line immediately after the | ||
| // opening "---" delimiter). The returned line numbers are absolute: they can be used | ||
| // directly as file:line positions for IDE-navigable error messages. | ||
| func extractTopLevelFieldLines(yamlContent string, frontmatterStart int) map[string]int { |
There was a problem hiding this comment.
[/zoom-out] This string-based YAML parsing approach is fragile compared to using the actual YAML parser's position tracking. The goccy/go-yaml library already provides line/column information in its AST.
Consider using yaml.NodeToValue() or yaml.ValueToNode() to access position metadata:
import "github.com/goccy/go-yaml"
func extractFieldLinesFromAST(yamlContent string) (map[string]int, error) {
var node yaml.Node
if err := yaml.Unmarshal([]byte(yamlContent), &node); err != nil {
return nil, err
}
// Walk the AST and extract Line from each MappingNode key
// This handles ALL YAML syntax correctly, not just simple cases
}This architectural choice would make the feature more robust and maintainable.
| // FieldLines is nil when there is no frontmatter | ||
| assert.Nil(t, result.FieldLines, "FieldLines should be nil when there is no frontmatter") | ||
| }) | ||
| } |
There was a problem hiding this comment.
[/tdd] Missing integration test for the full error flow. These unit tests verify extractTopLevelFieldLines works in isolation, but there's no test proving:
- A validation error in a workflow triggers with the correct line number
- The formatted compiler error includes
file:line:col:prefix - The error message is IDE-navigable
Consider adding an integration test:
func TestValidationErrorWithLocation_Integration(t *testing.T) {
markdownWithError := `---
engine: copiliot
tools:
github:
toolsets: default
---
# Test
`
compiler := NewCompiler()
err := compiler.Compile("test.md", markdownWithError)
require.Error(t, err)
// Should contain "test.md:2:" prefix (engine is on line 2)
assert.Contains(t, err.Error(), "test.md:2:")
assert.Contains(t, err.Error(), "copiliot")
}|
|
||
| // FieldLocation represents a source file location for a validation error. | ||
| // File and Line are optional; zero values mean "location unknown". | ||
| type FieldLocation struct { |
There was a problem hiding this comment.
[/zoom-out] The FieldLocation infrastructure only supports top-level frontmatter keys. Nested field validation errors (e.g., tools.github.toolsets) won't get location data.
This limitation means the most common validation errors (nested configuration) won't benefit from IDE navigation. Consider documenting this constraint in the struct comment:
// FieldLocation represents a source file location for a validation error.
// File and Line are optional; zero values mean "location unknown".
//
// Current limitation: Only top-level frontmatter keys are tracked.
// Nested field errors (e.g., tools.github.toolsets) will have Line=0.
type FieldLocation struct {Or, consider extending FieldLines to support dot-notation keys like "tools.github.toolsets": 4.
| line, column := 1, 1 | ||
| // Promote precise source location from WorkflowValidationError when available so that | ||
| // the emitted "file:line:col: error:" prefix points directly at the problematic field | ||
| // rather than always defaulting to line 1, column 1. |
There was a problem hiding this comment.
[/tdd] The location promotion logic silently overwrites filePath when vErr.File is set. This could be surprising if the caller passes a different file path.
Consider testing this edge case:
func TestFormatCompilerError_FilePathOverride(t *testing.T) {
loc := FieldLocation{File: "actual.md", Line: 5}
vErr := NewValidationErrorWithLocation("field", "val", "bad", "", loc)
// Caller passes "other.md" but error has "actual.md"
wrapped := formatCompilerError("other.md", "error", vErr.Error(), vErr)
// Which file wins? Should be documented.
assert.Contains(t, wrapped.Error(), "actual.md")
assert.NotContains(t, wrapped.Error(), "other.md")
}Also document the precedence in the function comment.
|
✅ PR Code Quality Reviewer completed the code quality review. |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
This comment has been minimized.
This comment has been minimized.
|
🧪 Test Quality Sentinel completed test quality analysis. |
There was a problem hiding this comment.
This PR adds valuable IDE-navigable error location tracking to validation errors. The implementation is mostly solid, but I've identified a few areas for improvement:
Key Findings
Correctness & Robustness:
- Loop variable capture issue in
extractTopLevelFieldLines(consider using explicit indexing) - Line number calculation formula is correct but could be clearer
- Potential file path override issue in error formatter when mixing relative/absolute paths
Maintainability:
- Some edge case handling could be more explicit (though current code works correctly)
- Test coverage could be expanded for malformed YAML edge cases
- Comments could better match the actual implementation details
What's Done Well
✅ Clear separation of concerns with FieldLocation struct
✅ Comprehensive test coverage for happy paths
✅ Good use of zero values to indicate "location unknown"
✅ Thoughtful handling of duplicate keys (first occurrence wins)
Overall, this is a well-structured feature that will significantly improve developer experience. The issues I've flagged are refinements rather than blockers.
Note
🔒 Integrity filter blocked 1 item
The following item was blocked because it doesn't meet the GitHub integrity level.
- #33466
pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none🔎 Code quality review by PR Code Quality Reviewer · ● 5.4M
| // directly as file:line positions for IDE-navigable error messages. | ||
| func extractTopLevelFieldLines(yamlContent string, frontmatterStart int) map[string]int { | ||
| fieldLines := make(map[string]int) | ||
| relLine := 0 |
There was a problem hiding this comment.
Loop variable capture bug: The line variable from strings.SplitSeq is reused across iterations. If you later reference it outside the loop (e.g., in deferred functions or goroutines), this could cause bugs. While not a problem in this specific code, it's safer to use:
for line := range strings.SplitSeq(yamlContent, "\n") {
lineCopy := line // Create copy for safe capture
relLine++
// ... rest of logic using lineCopy
}Or better yet, use the explicit index form to avoid any ambiguity:
lines := strings.Split(yamlContent, "\n")
for i, line := range lines {
relLine := i + 1
// ... rest of logic
}This makes the line numbering explicit and avoids potential capture issues.
| key := strings.TrimSpace(trimmed[:colonIdx]) | ||
| // Accept simple unquoted keys only. Bracket characters in the key position | ||
| // ({, }, [, ]) indicate inline YAML maps/sequences rather than plain string keys | ||
| // (e.g. `[anchor]: value` or `{implicit_key}: value`). These forms are not used |
There was a problem hiding this comment.
Line numbering inconsistency: The formula relLine + frontmatterStart - 1 is confusing and error-prone. Let me trace through an example:
frontmatterStart = 2(first content line after---)- First iteration:
relLine = 1(first line in YAML) - Calculation:
1 + 2 - 1 = 2✅ Correct
But this is harder to understand than necessary. Consider this clearer approach:
// absoluteLine = (relLine - 1) + frontmatterStart
// Which simplifies to the same formula, but the comment makes the offset clear
absoluteLine := frontmatterStart + relLine - 1Or even better, remove the magic -1 by starting relLine at 0:
relLine := 0
for line := range strings.SplitSeq(yamlContent, "\n") {
// ... logic ...
if key != "" && !strings.ContainsAny(key, " \t{}[]\"'") {
if _, alreadySeen := fieldLines[key]; !alreadySeen {
fieldLines[key] = frontmatterStart + relLine
}
}
relLine++
}This makes it immediately clear that we're adding the relative line offset to the frontmatter start position.
| if trimmed == "" || strings.HasPrefix(trimmed, "#") { | ||
| continue | ||
| } | ||
| // Top-level keys have no leading indentation |
There was a problem hiding this comment.
Missing edge case handling: The code checks for empty trimmed strings and comments, but what happens if a line contains ONLY a colon (:) or has the colon at position 0?
: valueThe current logic would extract an empty key (trimmed[:0]), which would then fail the key != "" check. However, this could be made more explicit:
colonIdx := strings.Index(trimmed, ":")
if colonIdx > 0 { // Changed from >= to > to skip colon-at-start
key := strings.TrimSpace(trimmed[:colonIdx])
if key != "" && !strings.ContainsAny(key, " \t{}[]\"'") {
// ... rest of logic
}
}Actually, the existing colonIdx > 0 check already handles this correctly! But the nested key != "" check is redundant since colonIdx > 0 guarantees at least one character before the colon. You could simplify:
if colonIdx > 0 {
key := strings.TrimSpace(trimmed[:colonIdx])
// No need for key != "" check - colonIdx > 0 ensures non-empty substring
if !strings.ContainsAny(key, " \t{}[]\"'") {
// ... rest of logic
}
}| // the emitted "file:line:col: error:" prefix points directly at the problematic field | ||
| // rather than always defaulting to line 1, column 1. | ||
| var vErr *WorkflowValidationError | ||
| if errors.As(cause, &vErr) && vErr.Line > 0 { |
There was a problem hiding this comment.
Potential nil pointer dereference: While errors.As guarantees vErr is non-nil after a successful match, the code accesses vErr.Line, vErr.Column, and vErr.File without checking if these are valid values. This is actually safe because the struct fields are value types (int, string), but the logic has a subtle issue:
If vErr.Line > 0 but vErr.File == "", you'll use the filePath parameter. However, if vErr.File != "", you override filePath even if the caller's filePath was more specific. This could lead to incorrect file paths in error messages.
Consider this edge case:
- Caller passes
filePath = "/absolute/path/workflow.md" vErr.File = "workflow.md"(relative path)- Result: Error message points to relative path instead of absolute path
Recommendation:
if errors.As(cause, &vErr) && vErr.Line > 0 {
line = vErr.Line
if vErr.Column > 0 {
column = vErr.Column
}
// Only override filePath if vErr.File is non-empty AND is an absolute path
if vErr.File != "" && filepath.IsAbs(vErr.File) {
filePath = vErr.File
}
}Or better yet, document that FieldLocation.File should always contain absolute paths, and add validation in NewValidationErrorWithLocation.
| // Skip empty lines and YAML comments | ||
| trimmed := strings.TrimSpace(line) | ||
| if trimmed == "" || strings.HasPrefix(trimmed, "#") { | ||
| continue |
There was a problem hiding this comment.
Comment clarity issue: The comment says "Top-level keys have no leading indentation" but the check is line[0] != ' ' && line[0] != '\t'. This doesn't account for:
- Mixed whitespace: A line starting with
\t(tab+space) would pass this check but is still indented - Other whitespace: Non-breaking spaces or other Unicode whitespace characters
While these are rare in YAML files, the comment should be more precise:
// Top-level keys start at column 0 (no leading space or tab)
if len(line) > 0 && line[0] != ' ' && line[0] != '\t' {Or use a more robust check:
// Top-level keys have no leading whitespace
if len(trimmed) > 0 && trimmed == line {
// trimmed == line means no leading/trailing whitespace was removedThis makes the intent clearer and handles all whitespace types correctly.
| yamlContent: `# workflow config | ||
| engine: copilot | ||
|
|
||
| on: push`, |
There was a problem hiding this comment.
Missing test coverage for malformed YAML: The tests cover happy paths and some edge cases, but don't test how the parser handles malformed YAML that could cause issues:
{
name: "malformed YAML with no colon",
yamlContent: `engine copilot
on push`,
frontmatterStart: 2,
wantFieldLines: map[string]int{}, // Should skip lines without colons
},
{
name: "keys with special characters",
yamlContent: `"key-with-quotes": value
key[0]: value
{inline}: value`,
frontmatterStart: 2,
wantFieldLines: map[string]int{}, // Should skip non-simple keys
},
{
name: "indented top-level key with tab",
yamlContent: `\tengine: copilot`,
frontmatterStart: 2,
wantFieldLines: map[string]int{}, // Should skip indented lines
},These tests would verify that the parser correctly handles edge cases mentioned in the code comments.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd (test-driven development) and /zoom-out (architectural consistency) based on this feature addition with comprehensive test coverage.
Key Themes
Test Coverage:
- ✅ Excellent table-driven tests for the core parsing logic
⚠️ Missing edge cases: zero-column handling, nested key name collisions⚠️ Weak assertions in some tests (e.g., checking for"3"instead of verifying"15:3"format)
Code Quality:
⚠️ Potential bug in column default handling (line 37 ofcompiler_error_formatter.go)⚠️ Minor performance issue: doubleTrimSpace()call per line in hot path⚠️ Comment clarity: offset calculation could explain the "-1" more explicitly
Positive Highlights
- ✅ Clean architectural layering:
FieldLocation→ValidationError→CompilerErroris well-structured - ✅ Backward compatibility preserved: Existing errors without location still work (defaults to 1:1)
- ✅ Thoughtful edge case handling: Comments, blank lines, duplicate keys, special characters all covered
- ✅ Clear value proposition: IDE-navigable errors are a significant UX improvement
Verdict
The feature is solid and well-tested overall. The inline comments identify specific improvements that would strengthen the implementation:
- Fix the column zero-value handling bug
- Add missing test cases for edge scenarios
- Tighten test assertions to verify exact format
- Minor optimizations and comment clarity
None of these are blockers, but addressing them (especially #1) would prevent subtle bugs in production.
Learn more about the applied skills:
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 5.2M
| return formatCompilerErrorWithPosition(filePath, 1, 1, errType, message, cause) | ||
| line, column := 1, 1 | ||
| // Promote precise source location from WorkflowValidationError when available so that | ||
| // the emitted "file:line:col: error:" prefix points directly at the problematic field |
There was a problem hiding this comment.
[/tdd] Potential bug: Column value handling is inconsistent.
The code checks vErr.Column > 0 but then unconditionally assigns column = vErr.Column, which could still be 0 if the check fails:
if vErr.Column > 0 {
column = vErr.Column // This still assigns 0 if Column == 0
}This means errors with Line: 10, Column: 0 will produce file:10:0: instead of file:10:1:. Consider:
if vErr.Column > 0 {
column = vErr.Column
} // else keep column = 1 (already set above)Add a test case for FieldLocation{Line: 10, Column: 0} to verify the expected behavior.
| // directly as file:line positions for IDE-navigable error messages. | ||
| func extractTopLevelFieldLines(yamlContent string, frontmatterStart int) map[string]int { | ||
| fieldLines := make(map[string]int) | ||
| relLine := 0 |
There was a problem hiding this comment.
[/zoom-out] Minor performance: strings.TrimSpace() is called twice per line.
Line 32 trims the line, then line 39 trims again when checking for the colon. Consider:
trimmed := strings.TrimSpace(line)
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
continue
}
if len(line) > 0 && line[0] != ' ' && line[0] != '\t' {
colonIdx := strings.Index(trimmed, ":")
if colonIdx > 0 {
key := trimmed[:colonIdx] // Already trimmed
// ...
}
}Not a blocker, but frontmatter parsing is on the hot path during compilation.
| "tools": 3, | ||
| "on": 6, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
[/tdd] Test coverage gap: Missing edge case for nested key name collision.
The tests verify nested keys are excluded, but what happens when a nested key has the same name as a top-level key? Example:
tools: # line 2
nested:
tools: # line 4 - same name, but nested
value: xShould FieldLines["tools"] be 2 (first occurrence wins)? Add a test case to document this behavior explicitly.
|
|
||
| wrapped := formatCompilerError("workflow.md", "error", vErr.Error(), vErr) | ||
| require.Error(t, wrapped) | ||
|
|
There was a problem hiding this comment.
[/tdd] Test assertion is weak: doesn't verify column format.
The test creates Column: 3 and asserts the string contains "3", but doesn't verify the format is actually line:column and not column:line or some other arrangement.
Consider a more specific assertion:
assert.Contains(t, errStr, "15:3", "Should format as line:column")Or use a regex to verify the exact format: workflow.md:15:3: error:
| // (e.g. `[anchor]: value` or `{implicit_key}: value`). These forms are not used | ||
| // in workflow frontmatter, so we skip them to avoid false positives. | ||
| // Quoted YAML keys such as `"key[0]"` are also not used in workflow frontmatter | ||
| // and are excluded by this check (the extracted substring will contain the quote). |
There was a problem hiding this comment.
[/zoom-out] Comment could be clearer about the offset calculation.
// absoluteLine = relLine + frontmatterStart - 1 is correct but doesn't explain why we subtract 1.
Consider:
// Convert relative line number (1-based within YAML) to absolute file line:
// relLine=1 + frontmatterStart=2 - 1 = line 2 (first line after '---')
fieldLines[key] = relLine + frontmatterStart - 1This helps future readers understand the indexing immediately.
🧪 Test Quality Sentinel ReportTest Quality Score: 90/100✅ Excellent (with minor caution on test inflation)
Test Classification Summary
Test Inflation Analysis
Impact: 10-point penalty applied to final score (reduced from 100 to 90). Note: The inflation is primarily due to comprehensive table-driven test cases with multiple edge cases per function. This is acceptable given the critical nature of error reporting, but worth noting for future reference. Detailed Test Analysis📊 View Per-Test Quality Assessment✅
|
|
|
Validation errors lacked source location context, forcing users to manually search workflow files for the problematic field. This PR adds
file:line:col:positioning to validation errors so IDE tooling can jump directly to the offending line.Infrastructure
FieldLocationstruct (File,Line,Column) added topkg/workflow/workflow_errors.goWorkflowValidationErrorextended withFile,Line,ColumnfieldsNewValidationErrorWithLocationconstructor for errors with known source positionsError()format: omits timestamp whenLine > 0— cleaner when the compiler already prefixesfile:line:col:Error formatting
formatCompilerErrornow promotes location from*WorkflowValidationErrorinstead of always defaulting to1:1:Line tracking in the parser
FrontmatterResult.FieldLines map[string]int— absolute 1-based line numbers for every top-level YAML key, populated by newextractTopLevelFieldLines(text scan, no AST overhead)WorkflowData.FrontmatterFieldLines— surfaced to all validation functions so they can look up line numbers when creating errorsWarning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
https://api.github.com/graphql/usr/bin/gh gh repo view --json owner,name --jq .owner.login + "/" + .name 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh repo view --json owner,name --jq .owner.login + "/" + .name At,event,headBranch,headSha,displayTitle GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh pr list --repo github/gh-aw --state all --author app/github-actions --search created:2026-05-11T23:58:00Z..2026-05-12T00:05:00Z --limit 1 --json number --jq .[0].number GOMOD GOMODCACHE go(http block)https://api.github.com/orgs/owner/actions/secrets/usr/bin/gh gh api /orgs/owner/actions/secrets --jq .secrets[].name go1.25.8 -c=4 -nolocalimports -importcfg /tmp/go-build2643043042/b525/importcfg -pack /tmp/go-build2643043042/b525/_testmain.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/orgs/test-owner/actions/secrets/usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv ithub/workflows/agent-performance-analyzer.md -buildtags 3043042/b555=> -errorsas b/gh-aw/pkg/semv-1 -nilfunc git comm�� ithub-script/git/ref/tags/v9 initial commit bject.type] | @tsv -json GO111MODULE 64/bin/go 3043042/b555/importcfg(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v3/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv architecture-guardian.md o 1/x64/bin/node GOINSECURE GOMOD GOMODCACHE 3043042/b394/importcfg t-ha�� vaScript3106012653/001/test-frontmatter-with-nes-errorsas GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v5/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv 495/001/stability-test.md GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x--jq env 5619-33208/test-3223998073/.github/workflows GO111MODULE 1/x64/bin/node GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote.origin.url(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv 9DSwdag_RvDB2FtdE3Xz/9DSwdag_RvDB2FtdE3Xz 3043042/b541/_testmain.go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile go1.25.8 -c=4 -nolocalimports /opt/hostedtoolcache/go/1.25.8/x--jq -V=f�� -aw/git/ref/tags/v3.0.0 /tmp/go-build2643043042/b498/_testmain.go ache/node/24.14.1/x64/bin/node -json GO111MODULE 64/bin/go ache/node/24.14.1/x64/bin/node(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv -stringintconv -tests /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/vet node /tmp�� /home/REDACTED/work/gh-aw/gh-aw/.github/workflows/api-consumption-report.md resolved$(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v6/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json piler}} /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env ExpressionCompiledOutput3034362390/001(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 528171551/.github/workflows GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v8/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv sistency_KeyOrdering2540445059/001/test1.md {{context.GOARCH}} {{context.Compiler}} /usr/bin/gh unsafe GO111MODULE 64/bin/go gh api ithub-script/git/ref/tags/v9 --jq bject.type] | @tsv -json GO111MODULE 64/bin/go git(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv k/gh-aw/gh-aw/.github/workflows/agent-performance-analyzer.md -trimpath /usr/bin/gh -p github.com/githurev-parse -lang=go1.25 gh api /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git -c=4 -nolocalimports -importcfg git(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v9/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -d main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -p golang.org/x/tooenv -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -p main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v9.0.0/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -p golang.org/x/tooenv -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -p main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv /tmp/go-build243GOINSECURE -trimpath 64/bin/go -p github.com/githuenv -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/setup-go/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -bool -buildtags /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.8/x--jq -o /tmp/go-build2643043042/b497/_pkg_.a url .cfg -p github.com/githu-1 -lang=go1.25 3043042/b562/stats.test(http block)https://api.github.com/repos/actions/setup-node/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile env g_.a GO111MODULE r: $owner, name: $name) { hasDiscussionsEnabled } } s eutil GOMODCACHE cutil.test(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv 4dh0uLCKc -buildtags 1/x64/bin/node -errorsas -ifaceassert -nilfunc ortcfg t-ha�� ithub/workflows/archie.md g/stringutil/identifiers.go 3043042/b538/_pkg_.a -errorsas -ifaceassert -nilfunc /usr/lib/git-core/git(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv git-upload-pack '/tmp/TestParseDefaultBranchFromLsRemoteWithReal-errorsas l /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/link -json GO111MODULE 64/bin/go /opt/hostedtoolc--package-lock-only -V=f�� GOMODCACHE go .0/x64/bin/go -json GO111MODULE 64/bin/go git(http block)https://api.github.com/repos/actions/setup-node/git/ref/tags/v6/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env ll-sweep (enforce_all)' GO111MODULE e/git l GOMOD GOMODCACHE e/git(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 3043042/b498/fileutil.test GOINSECURE GOMOD GOMODCACHE 3043042/b498/filowner/test-repo e=/t�� t0 GO111MODULE(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xowner/test-repo env 528171551/.github/workflows GO111MODULE 3043042/b432/vet.cfg GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 3043042/b505/jsonutil.test GOINSECURE GOMOD GOMODCACHE 3043042/b505/jsoowner/repo e=/t�� /ref/tags/v9.0.0 GO111MODULE sv m0s GOMOD(http block)https://api.github.com/repos/aws-actions/configure-aws-credentials/git/ref/tags/v4/usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv run url /usr/bin/git --detach GO111MODULE 64/bin/go git -C /tmp/gh-aw-test-runs/20260520-055619-33208/test-3640699418/.github/workflows l ache/node/24.14.1/x64/bin/node remote.upstream.grep GO111MODULE 64/bin/go ache/node/24.14./tmp/gh-aw/aw-master.patch(http block)/usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 -importcfg bject.type] | @tsv -s -w -buildmode=exe git -C image:v1.0.0 config ache/node/24.14.1/x64/bin/node remote.origin.urgit GO111MODULE 64/bin/go ache/node/24.14.1/x64/bin/node(http block)https://api.github.com/repos/azure/login/git/ref/tags/v2/usr/bin/gh gh api /repos/azure/login/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv 3043042/b571/_pkg_.a git-upload-pack '/tmp/TestParseDefaultBranchFromLsRemoteWithRealGitbranch_with_hunsafe ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -json GO111MODULE 64/bin/go ache/go/1.25.8/x64/pkg/tool/linu--jq -C AGoV/wVIjl6JE2QkluJttAGoV config e/git remote.origin.ur/usr/lib/git-core/git GO111MODULE 64/bin/go e/git(http block)https://api.github.com/repos/docker/login-action/git/ref/tags/v3/usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9.0.0 --auto bject.type] | @tsv --detach GO111MODULE 64/bin/go /tmp/go-build2643043042/b545/log--jq -tes�� -test.paniconexit0 s/12346/artifacts /usr/bin/git -test.timeout=10git -test.run=^Test -test.short=true. git(http block)https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv t0 -buildtags r: $owner, name: $name) { hasDiscussionsEnabled } } m0s -ifaceassert(http block)https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv 5619-33208/test-3640699418/.gith-c=4 GO111MODULE ache/go/1.25.8/x64/pkg/tool/linu-importcfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x--jq env OKEN }} GO111MODULE sv GOINSECURE GOMOD GOMODCACHE(http block)https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv 5619-33208/test-1692733353/.github/workflows 3043042/b455/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env st-1589422392 GO111MODULE r: $owner, name: $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-05-13 GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-04-20 GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-02-19 GOMOD GOMODCACHE 64/pkg/tool/linuorigin env -json oFiles,IgnoredOt-nolocalimports 64/pkg/tool/linu-importcfg GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/home/REDACTED/work/gh-aw/gh-aw/pkg/syncutil/onceloader_test.go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name .cfg ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env y_with_explicit_@{u} GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run download 1 --dir test-logs/run-1 test.go ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env edOutput544737685/001 GO111MODULE 64/pkg/tool/linux_amd64/asm GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/asm(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE pBvTgXO/DnQKkYlYtest@example.com env 2362163896/.github/workflows GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu^remote\..*\.gh-resolved$(http block)/usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env report.md GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/1234567890/usr/bin/gh gh api repos/{owner}/{repo}/actions/runs/1234567890 --jq {databaseId: .id, number: .run_number, url: .html_url, status: .status, conclusion: .conclusion, workflowName: .name, workflowPath: .path, createdAt: .created_at, startedAt: .run_started_at, updatedAt: .updated_at, event: .event, headBranch: .head_branch, -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env e-analyzer.md GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE 5v/xGCZYgHhEK_tLconfig GOMODCACHE go env or.md GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name .cfg ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env y.md GO111MODULE k GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 29522563/001 GO111MODULE ck GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env rdian.md GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE ortcfg(http block)/usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuorigin env edOutput544737685/001 GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name oFiles,IgnoredOtherFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFremote 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE sY5xy3c/9ezsDU_Vstatus env rdian.md GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE til GOMODCACHE go(http block)/usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuremote.origin.url epOn�� mpiledOutput4076594964/001 GO111MODULE ortcfg.link GOINSECURE GOMOD GOMODCACHE LBy97bxPkfrkiwhLXh/3XLIOuLPxEGBR-trimpath(http block)https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts/usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name l_test.go ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env y.md GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User(http block)/usr/bin/gh gh run download 5 --dir test-logs/run-5 .cfg ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env mpiledOutput184441634/001 GO111MODULE 64/pkg/tool/linux_amd64/asm GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com(http block)https://api.github.com/repos/github/gh-aw/actions/workflows/usr/bin/gh gh workflow list --json name,state,path -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE x_amd64/vet env -json herFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,Tconfig 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 setup/js/node_moconfig GOMODCACHE 64/pkg/tool/linutest@example.com env 3623416137/.github/workflows GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link(http block)https://api.github.com/repos/github/gh-aw/contents/.github/workflows/shared/reporting.md/tmp/go-build2643043042/b478/cli.test /tmp/go-build2643043042/b478/cli.test -test.testlogfile=/tmp/go-build2643043042/b478/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true -p github.com/githuenv -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/dev/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/dev --jq [.object.sha, .object.type] | @tsv /ref/tags/v9.0.0 --jq sv -json GO111MODULE 64/bin/go git -C /tmp/TestGuardPolicyTrustedUsersRequiresMinIntegrity3285162960/001 config /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet remote.origin.urinfocmp git 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/dev --jq [.object.sha, .object.type] | @tsv 3043042/b593/_pkg_.a go 3043042/b593=> -json GO111MODULE 64/bin/go git conf�� poJ_/sX9FX53sm1OTZ6jdpoJ_ Test User /usr/bin/git -json GO111MODULE 64/bin/go git(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv t0 /dev/null .test m0s -nolocalimports(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv t1848615406/.github/workflows GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 495/001/stability-test.md GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env ub/workflows GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/issues/17/usr/bin/gh gh api repos/github/gh-aw/issues/17 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/google-github-actions/auth/git/ref/tags/v2/usr/bin/gh gh api /repos/google-github-actions/auth/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv runs/20260520-055619-33208/aw-manifest-legacy-747511632/.github/workflows --revs /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet l --delta-base-off-1 -q /opt/hostedtoolcache/go/1.25.8/x--jq -ato�� -bool(http block)https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv t1848615406/.github/workflows GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/pkg/tool/linu-buildmode=exe GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xorigin(http block)https://api.github.com/repos/nonexistent/repo/actions/runs/12345/usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE ters.test 6430�� dgWJmpNjg GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)https://api.github.com/repos/org/repo/pulls/1/usr/bin/gh gh api repos/org/repo/pulls/1 go env 01 02/work 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/actions/secrets/usr/bin/gh gh api /repos/owner/repo/actions/secrets --jq .secrets[].name go1.25.8 -c=4 -nolocalimports -importcfg /tmp/go-build2643043042/b522/importcfg -pack /tmp/go-build2643043042/b522/_testmain.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-remote-workflow --limit 30 --repo owner/repo yLNKNaz/um86pbnuaZfPHtRi8CIm 6430�� -json GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuremote2(http block)/usr/bin/gh gh workflow list --repo owner/repo --json name,path,state 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuremote.origin.url env 53/001/test-frontmatter-with-arrays.md GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link(http block)https://api.github.com/repos/test-owner/test-repo/actions/secrets/usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/test/repo/usr/bin/gh gh api /repos/test/repo --jq .default_branch -json GO111MODULE ck GOINSECURE GOMOD GOMODCACHE go sRem�� nifest-legacy-747511632/.github/workflows GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x--json(http block)If you need me to access, download, or install something from one of these locations, you can either: