Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

The compiler was reporting validation errors at the wrong line, adding duplicate "✗" prefixes, and showing confusing relative paths with ".." components. For nested safe-outputs configurations, errors pointed to parent keys instead of the actual invalid property.

Example:

safe-outputs:
  create-discussion:
  missing-tool:
    create-discussion: true  # Error should point here (line 6)

Previously reported error at line 4, now correctly reports at line 6.

Changes

Parser location tracking (pkg/parser/json_path_locator.go)

  • Fixed indentation level calculation in findNestedSection(): changed lineLevel == currentLevel*2 to lineLevel == currentLevel
  • Adjusted base indent calculations to match YAML structure

Error message formatting (pkg/cli/compile_helpers.go, cmd/gh-aw/main.go)

  • Removed redundant console.FormatErrorMessage() wrappers that added duplicate "✗" prefixes
  • Updated main error handler to detect console.FormatError pattern (file:line:column:) and skip re-wrapping

Path display clarity (pkg/console/console.go, pkg/console/console_test.go)

  • Modified ToRelativePath() to use absolute paths when relative paths contain ".." for better clarity
  • Files within the working directory still show clean relative paths
  • Updated tests to expect absolute paths for files outside working directory

Comprehensive test coverage (pkg/parser/safe_outputs_error_location_test.go, pkg/parser/schema_validation_depth_test.go)

  • Added 18 new test cases covering errors at depths 1-4
  • Tests include the original bug case, complex workflows, edge cases
  • End-to-end integration tests validate complete error formatting pipeline

Before:

✗ ✗ .github/workflows/test.md:4:3: error: Unknown property: create-discussion...

After (file outside repository):

/tmp/test.md:6:5: error: Unknown property: create-discussion...

After (file inside repository):

.github/workflows/test.md:6:5: error: Unknown property: create-discussion...

Test Coverage

New test files:

  • safe_outputs_error_location_test.go - 12 unit tests for various nesting depths
  • schema_validation_depth_test.go - 6 integration tests for end-to-end validation

Test scenarios:

  • Depth 1: Root level and direct safe-outputs children
  • Depth 2: Nested under handlers (original bug case with missing-tool)
  • Depth 3: Handler configurations (create-issue, github-token, labels)
  • Depth 4: Very deep nesting with arrays
  • Edge cases: empty sections, comments, multiple errors, non-existent paths

All tests validate correct line numbers, column positions, and error message formatting.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot stopped work on behalf of pelikhan due to an error February 10, 2026 20:09
Copilot stopped work on behalf of pelikhan due to an error February 10, 2026 20:09
Copilot AI and others added 2 commits February 10, 2026 20:22
- Fix nested section indentation level calculation in json_path_locator.go
- Remove redundant FormatErrorMessage wrapper in compile_helpers.go
- Remove redundant FormatValidationError wrapper in main.go compile command
- Update main error handler to detect console.FormatError pattern

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
All tests passing. Both issues resolved:
- Error location now correct (line 6 instead of line 4)
- No double check mark prefix (clean IDE-parseable format)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
Copy link
Contributor

@copilot keep working

Copilot AI changed the title [WIP] Fix error location in workflow configuration Fix error location and double prefix for nested safe-outputs validation errors Feb 10, 2026
Copilot AI requested a review from pelikhan February 10, 2026 20:27
@pelikhan
Copy link
Contributor

@copilot file path looks suspicious:

../../../../../tmp/test.md

switch to absolute path if it contains ..

Copy link
Contributor Author

Copilot AI commented Feb 10, 2026

@copilot keep working

The PR is complete and working correctly. Both issues have been fixed:

  1. Error location: Now correctly points to line 6 (the nested create-discussion: true under missing-tool) instead of line 4
  2. No double prefix: Clean IDE-parseable format without duplicate "✗" symbols

All tests pass:

  • Parser location tests ✓
  • Workflow compilation (148 workflows) ✓
  • Code formatting ✓

Example output:

../../../../../tmp/test.md:6:5: error: Unknown property: create-discussion...
6 |     create-discussion: true
        ^^^^^^^^^^^^^^^^^

@pelikhan
Copy link
Contributor

@copilot add more tests with syntax errors at various tree depth

When a relative path contains "..", display the absolute path instead
for better clarity. This prevents confusing paths like
"../../../../../tmp/test.md" and shows "/tmp/test.md" instead.

Files within the working directory still show clean relative paths
like ".github/workflows/test.md".

Addresses feedback from @pelikhan

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 10, 2026

@copilot file path looks suspicious:

...

Fixed in commit ac40d83. When relative paths contain "..", the absolute path is now displayed instead.

Before:

../../../../../tmp/test.md:6:5: error: Unknown property...

After:

/tmp/test.md:6:5: error: Unknown property...

Files within the repository still show clean relative paths:

.github/workflows/test.md:6:5: error: Unknown property...

Copilot AI changed the title Fix error location and double prefix for nested safe-outputs validation errors Fix error location, double prefix, and confusing paths for nested safe-outputs validation errors Feb 10, 2026
Added two new test files to validate error location accuracy:

1. safe_outputs_error_location_test.go:
   - 12 test cases for errors at depths 1-4
   - Tests original bug case (depth 2 nested under missing-tool)
   - Tests complex workflows with multiple sections
   - Tests edge cases (empty sections, arrays, comments)

2. schema_validation_depth_test.go:
   - 6 end-to-end integration tests
   - Tests errors at root, safe-outputs, handlers, tools, and permissions
   - Validates complete error formatting pipeline

All 18 new test cases pass, covering:
- Depth 1: Root level properties
- Depth 2: Properties in safe-outputs, tools, permissions
- Depth 3: Properties in handlers (create-issue, create-discussion, github-token)
- Depth 4: Very deeply nested properties

Addresses feedback from @pelikhan

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 10, 2026

@copilot add more tests with syntax errors at various tree depth

Added comprehensive tests in commit 49f1d58. Created 18 new test cases covering syntax errors at depths 1-4:

Test files:

  • safe_outputs_error_location_test.go - 12 unit tests for location detection
  • schema_validation_depth_test.go - 6 integration tests for end-to-end validation

Coverage:

  • Depth 1: Root level properties
  • Depth 2: Properties in safe-outputs, permissions (original bug case)
  • Depth 3: Properties in handlers (create-issue, github-token)
  • Depth 4: Very deeply nested properties with arrays

All tests pass, including the original bug case where errors in missing-tool were incorrectly pointing to line 4 instead of line 6.

…ng directory

Updated TestFormatErrorWithAbsolutePaths to expect absolute paths when
files are outside the working directory, consistent with the new behavior
of ToRelativePath() that avoids confusing paths with ".." components.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review February 10, 2026 21:01
Copilot AI review requested due to automatic review settings February 10, 2026 21:01
@github-actions
Copy link
Contributor

🛡️ Security Posture Analysis

This PR contains changes that may affect the security posture. Please review the following concerns:

🟠 Input validation: dangerous-property filtering removed

Location: pkg/workflow/expression_validation.go and pkg/constants/constants.go

Change Detected:

-// validateExpressionForDangerousProps checks if an expression contains dangerous JavaScript
-// property names that could be used for prototype pollution or traversal attacks.
-// This matches the JavaScript runtime validation in actions/setup/js/runtime_import.cjs
-// Returns an error if dangerous properties are found.
-func validateExpressionForDangerousProps(expression string) error {
-    ...
-}
-
 // validateSingleExpression validates a single literal expression
 func validateSingleExpression(expression string, opts ExpressionValidationOptions) error {
        expression = strings.TrimSpace(expression)
 
-       // First, check for dangerous JavaScript property names that could be used for
-       // prototype pollution or traversal attacks (PR #14826)
-       if err := validateExpressionForDangerousProps(expression); err != nil {
-               return err
-       }
-
        // Check if this expression is in the allowed list
@@
-// DangerousPropertyNames contains JavaScript built-in property names that are blocked
-// in GitHub Actions expressions to prevent prototype pollution and traversal attacks.
-// This list matches the DANGEROUS_PROPS list in actions/setup/js/runtime_import.cjs
-// See PR #14826 for context on these security measures.
-var DangerousPropertyNames = []string{
-       "constructor",
-       "__proto__",
-       "prototype",
-       "__defineGetter__",
-       "__defineSetter__",
-       "__lookupGetter__",
-       "__lookupSetter__",
-       "hasOwnProperty",
-       "isPrototypeOf",
-       "propertyIsEnumerable",
-       "toString",
-       "valueOf",
-       "toLocaleString",
-}

Security Impact: Removing the dangerous-property check and the corresponding constant means expressions that use constructor, __proto__, prototype, etc. now pass compile-time validation, which reopens the prototype-pollution/traversal attack vector that the previous validation deliberately blocked.

Recommendation: Reintroduce the dangerous-property validation (and the DangerousPropertyNames list) so that expressions touching those reserved properties continue to fail validation before reaching runtime.


Summary

Category Severity Count
Input Validation 🟠 1

Note: This is an automated analysis. Please verify these findings and determine if the changes are intentional and justified.

AI generated by Security Guard Agent 🛡️

@pelikhan pelikhan merged commit 0a758a8 into main Feb 10, 2026
129 checks passed
@pelikhan pelikhan deleted the copilot/fix-syntax-error-in-workflow branch February 10, 2026 21:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves schema/safe-outputs validation error reporting by fixing incorrect source locations, eliminating duplicated error prefixes, and making displayed file paths clearer (especially for files outside the working directory). It also adds new tests to cover error-location behavior across multiple nesting depths.

Changes:

  • Fix indentation-level handling in nested YAML section detection to report correct error locations.
  • Reduce redundant error message formatting/wrapping to avoid double “✗” prefixes.
  • Adjust path rendering to prefer absolute paths when a relative path would include .., plus add depth-focused tests.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/parser/schema_validation_depth_test.go Adds end-to-end tests asserting correct line reporting at multiple nesting depths.
pkg/parser/safe_outputs_error_location_test.go Adds focused tests for locating “additional properties” errors under safe-outputs at depths 1–4.
pkg/parser/json_path_locator.go Fixes nested section indentation/level calculations used for JSON-path-to-YAML location mapping.
pkg/console/console_test.go Updates tests for new ToRelativePath behavior and absolute-path expectations.
pkg/console/console.go Changes ToRelativePath to return absolute paths when relative paths would contain ...
pkg/cli/compile_helpers.go Stops wrapping compile errors with FormatErrorMessage, assuming they’re already formatted.
cmd/gh-aw/main.go Simplifies compile error propagation and adds detection to avoid double formatting at the top-level error handler.
Comments suppressed due to low confidence (1)

pkg/console/console_test.go:365

  • This absolute-path check is POSIX-specific (strings.HasPrefix(lines[0], "/")) and will fail on Windows where absolute paths don't start with /. Since the repo has Windows CI, prefer filepath.IsAbs(...) (and possibly filepath.VolumeName handling) to keep the test cross-platform.
	// Since tmpDir is outside the working directory (in /tmp), the path should be absolute
	// to avoid confusing relative paths with ".." components
	lines := strings.Split(output, "\n")
	if !strings.HasPrefix(lines[0], "/") {
		t.Errorf("Expected output to start with absolute path for files outside working directory, got: %s", lines[0])
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +320 to +323
// Absolute path within working directory should be converted to relative
// without ".." in the path
// The result should not start with / and should not contain ..
return !strings.HasPrefix(result, "/") && !strings.Contains(result, "..") && strings.HasSuffix(result, "test.md")
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions infer “relative path” by checking !strings.HasPrefix(result, "/"), which is not valid on Windows (absolute paths typically start with a drive letter, so an absolute path could still pass). Since CI runs windows-latest, use filepath.IsAbs(result) and/or validate the absence of .. segments after filepath.Clean instead of relying on / prefixes.

This issue also appears on line 360 of the same file.

Suggested change
// Absolute path within working directory should be converted to relative
// without ".." in the path
// The result should not start with / and should not contain ..
return !strings.HasPrefix(result, "/") && !strings.Contains(result, "..") && strings.HasSuffix(result, "test.md")
// Absolute path within working directory should be converted to a relative path
// that does not traverse upwards ("..") and is not absolute on any platform.
cleaned := filepath.Clean(result)
return !filepath.IsAbs(result) && !strings.Contains(cleaned, "..") && strings.HasSuffix(cleaned, "test.md")

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +71
// If the relative path contains "..", use absolute path instead for clarity
if strings.Contains(relPath, "..") {
return path
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ToRelativePath checks strings.Contains(relPath, ".."), which will also match legitimate directory/file names that include .. (e.g. some..dir/file.md) and incorrectly force an absolute path. Consider detecting .. as a path segment instead (split on filepath.Separator / use filepath.Clean + component scan), or check for patterns like .. at segment boundaries (relPath == "..", prefix ".."+sep, or contains sep+".."+sep).

Copilot uses AI. Check for mistakes.
Comment on lines 101 to 105
if err := CompileWorkflowWithValidation(compiler, file, verbose, false, false, false, false, false); err != nil {
// Always show compilation errors on new line
fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error()))
// Note: Don't wrap in FormatErrorMessage as the error is already formatted by console.FormatError
fmt.Fprintln(os.Stderr, err.Error())
stats.Errors++
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compileSingleFile now prints err.Error() directly. CompileWorkflowWithValidation can return plain/unformatted errors (e.g. lockfile YAML validation failures or security-scan wrapper errors in pkg/cli/compile_validation.go), so this is a UX regression vs the previous console.FormatErrorMessage(...) behavior. Suggest conditionally formatting only when the message isn't already in console.FormatError/suggestions/✗ form (similar to main()), or format these non-console.FormatError errors at the source before returning.

Copilot uses AI. Check for mistakes.
Comment on lines +315 to +317
// Get current working directory and construct a path within it
wd, _ := os.Getwd()
return filepath.Join(wd, "pkg/console/test.md")
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test builds an absolute path from os.Getwd() but ignores the returned error. If Getwd() fails in some environments, this will silently generate a bad path and can make the test behave unpredictably; please handle the error (e.g., require.NoError(t, err) / t.Fatalf(...)).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants