Preserve error chain in ErrorCollector.FormattedError for multi-error aggregation#27765
Preserve error chain in ErrorCollector.FormattedError for multi-error aggregation#27765
ErrorCollector.FormattedError for multi-error aggregation#27765Conversation
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b758b343-8fb6-493f-b705-1cbbd8e31b11 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
This reverts commit 2133c72. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b758b343-8fb6-493f-b705-1cbbd8e31b11 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
ErrorCollector.FormattedError for multi-error aggregation
There was a problem hiding this comment.
Pull request overview
This PR fixes ErrorCollector.FormattedError so that aggregated multi-errors preserve wrapped error identity, allowing callers to correctly use errors.Is/errors.As on formatted aggregate errors.
Changes:
- Updated
ErrorCollector.FormattedError(category)to wraperrors.Join(c.errors...)with%wwhile retaining the count header. - Added tests asserting
errors.Isanderrors.Astraversal works throughFormattedErrorresults.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/workflow_errors.go | Preserve error chains in formatted multi-error output by wrapping errors.Join(...) with %w. |
| pkg/workflow/error_aggregation_test.go | Add regression tests verifying errors.Is/errors.As work through FormattedError. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0
🧪 Test Quality Sentinel ReportTest Quality Score: 80/100✅ Excellent test quality
Test Classification Details
Analysis
The test:
|
There was a problem hiding this comment.
✅ Test Quality Sentinel: 80/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). The new test TestErrorCollectorFormattedError_PreservesErrorChain is a high-value behavioral design test that directly enforces the error chain contract introduced by this PR.
ErrorCollector.FormattedErrorformatted multi-error output by stringifying collected errors, which dropped wrapped error identity and brokeerrors.Is/errors.Astraversal. This path is used by validation flows, so callers could no longer reliably introspect specific underlying errors.Error aggregation behavior
FormattedError(category)to keep the human-readable count header while wrappingerrors.Join(c.errors...)with%w.Error chain preservation tests
error_aggregation_test.goto assert:errors.Ismatches a wrapped sentinel error returned throughFormattedError.errors.Asextracts a wrapped typed error returned throughFormattedError.Resulting pattern
Warning
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/pkg/tool/linux_amd64/vet GOINSECURE g/x/crypto/cryptconfig 6287196/b006/symuser.name 64/pkg/tool/linuTest User(http block)/usr/bin/gh gh repo view owner/repo env 6287196/b241/_pkg_.a r73k/ZR15bOYtzO_sNGC5r73k ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE t/internal/langurev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh repo view owner/repo env 2747813275/.github/workflows k-ff/hcoMcb4nJlDk1Ubnk-ff ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE b/gh-aw/pkg/giturev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true(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 x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)/usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -c=4 -nolocalimports -importcfg /tmp/go-build1888311829/b390/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/internal/tools/actions-build/main.go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node(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 --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/gh 3597738024/.githgit fg 64/pkg/tool/linu--show-toplevel gh repo�� view owner/test-repo /usr/bin/git 153501083/.githunode BHdz/-6z_QJDvZKL/opt/hostedtoolcache/node/24.14.1/x64/bin/npm 64/pkg/tool/linuinstall git(http block)/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv . -v /opt/hostedtoolcache/go/1.25.8/x64/bin/bash ithub/workflows git kflows/daily-arc--show-toplevel bash --no�� --noprofile /opt/hostedtoolc{{context.GOARCH}} {{context.Compiler}} /usr/bin/git k/gh-aw/gh-aw/.gnode /home/REDACTED/wor/opt/hostedtoolcache/node/24.14.1/x64/bin/npm l-workflow.lock.install git(http block)/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/gh -json GO111MODULE 64/bin/go gh repo�� view owner/test-repo /usr/bin/git ut3925945361/001node GO111MODULE 64/pkg/tool/linuinstall git(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 tagedFiles2838180526/001/workflow.md -trimpath /usr/bin/git -p main -lang=go1.25 git conf�� --get remote.origin.url ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet ted-objects.md -c=4 -nolocalimports ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv in sync with .golangci.yml for consistency show /usr/bin/git --require tions/setup/js/nrev-parse r: $owner, name:--show-toplevel git -C /home/REDACTED/work/gh-aw/gh-aw/.github/workflows config ache/node/24.14.1/x64/bin/git remote.origin.urgit /home/REDACTED/worrev-parse ache/go/1.25.8/x--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv GOMODCACHE go om/org2/repo.git -json GO111MODULE 64/bin/go infocmp -1 xterm-color node /usr/bin/infocmp prettier --check 64/bin/go infocmp(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 6287196/b212/imp-errorsas -trimpath fg -p crypto/internal/diff -lang=go1.25 ache/go/1.25.8/x--name-only(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/go/1.25.8/x64/pkg/tool/linu-buildtags /usr/bin/git se 15932/b057/vet.c\n fg git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linu-tests /usr/bin/git 4401-33052/test-git k/gh-aw/gh-aw/pkrev-parse ache/go/1.25.8/x--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel x_amd64/vet 1/x64/bin/npm --show-toplevel -tests(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 /tmp/TestGuardPolicyMinIntegrityOnlymin-integrity_only_defaults_repo3011823016/0remote.origin.urgit rev-parse ache/node/24.14.1/x64/bin/node -json GO111MODULE x_amd64/compile git t-16�� k/gh-aw/gh-aw/.github/workflows/ace-editor.md git /usr/bin/git remote.origin.urgit GO111MODULE x_amd64/vet git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv RjYN7sUAg config n-dir/bash remote.origin.urgit FFiles,SFiles,Swrev-parse 1/x64/bin/node ortcfg -C g/timeutil/format.go rev-parse kflows/weekly-blog-post-writer.lock.yml --count tions/setup/js/nrev-parse bin/git git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv xterm-color -tests /usr/bin/git ck 'scripts/**/*git GO111MODULE 64/bin/go git -C /tmp/TestGuardPolicyBlockedUsersCommaSeparatedCompiledOutput1989721386/001 remote /usr/bin/git -json git 6f085b31ee0789e7--show-toplevel git(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 --show-toplevel x_amd64/link /usr/bin/git r.test -trimpath 64/pkg/tool/linu-b git rev-�� --show-toplevel J_/CWrYu2czG7Ca7ylQP4Z8/vCNYLdc7D8RXanEmFBss /usr/bin/git util.test /tmp/go-build356rev-parse gutil.test git(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git ithub/workflows rev-parse yml git rev-�� --show-toplevel git /usr/bin/git k/gh-aw/gh-aw/.ggit oFiles,IgnoredOtrev-parse x_amd64/asm git(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel go /usr/bin/git 5326-87184/test-git GO111MODULE 1/x64/bin/node git rev-�� --show-toplevel go /usr/bin/git SameOutput383731git GO111MODULE /opt/hostedtoolc--show-toplevel 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 -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json 8601/parse.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json gset/set.go x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json nal.go x_amd64/compile GOINSECURE GOMOD bytealg/indexbyt--show-toplevel x_amd64/compile env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(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 /home/REDACTED/work/gh-aw/gh-aw/.github/workflows/archie.md x_amd64/vet /opt/hostedtoolcache/node/24.14.1/x64/bin/node ortcfg fg 64/pkg/tool/linu--show-toplevel /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� Actor: ${{ github.actor }}, Repo: ${{ github.repository }} 64/pkg/tool/linux_amd64/vet /usr/bin/git y-test.md fg 64/pkg/tool/linu--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -x c /home/REDACTED/go/bin/git - /home/REDACTED/worrev-parse /home/REDACTED/wor--show-toplevel git ls-f�� --exclude-standard --others /usr/bin/git k/gh-aw/gh-aw st/dist/workers/rev-parse lock.yml git(http block)/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git init�� GOMODCACHE go /usr/bin/git mLsRemoteWithReagit mLsRemoteWithRearev-parse 64/bin/go git(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 --show-toplevel x_amd64/compile /opt/hostedtoolcache/node/24.14.1/x64/bin/node -json fg 64/pkg/tool/linu--show-toplevel /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� github.token 64/pkg/tool/linuInitial commit /usr/bin/git y-test.md fg 64/pkg/tool/linu--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -f {{context.GOARCH}} {{context.Compiler}} /opt/hostedtoolcache/uv/0.11.7/x86_64/git unsafe /home/REDACTED/worrev-parse repository(owne--show-toplevel git ls-f�� --exclude-standard --others /usr/sbin/bash ithub/workflows -importcfg /opt/hostedtoolc--show-toplevel bash(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel go /usr/bin/gh -json GO111MODULE 64/bin/go gh api /repos/actions/github-script/git/ref/tags/v9 --jq /usr/bin/git -json GO111MODULE 64/bin/go /usr/bin/git(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 --show-toplevel -dwarf=false /usr/bin/git go1.25.8 -c=4 -nolocalimports git rev-�� s/test.md /tmp/go-build35615932/b420/_testmain.go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile -json t/format.go x_amd64/compile /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/compile(http block)/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv k/gh-aw/gh-aw/.github/workflows show /usr/bin/git l tions/setup/js/nrev-parse r: $owner, name:--show-toplevel git -C k/gh-aw/gh-aw/.github/workflows config 1/x64/bin/bash remote.origin.urgit 7a714ef2b2a60e12rev-parse repository(owne--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv run(http block)https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b/usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv --count 4171bb75..HEAD $name) { hasDiscussionsEnabled } } README.md ion-test..token-config bin/git git rev-�� HEAD 4171bb75 tnet/tools/git token-test.txt(http block)/usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv 4171bb75..HEAD --stdout modules/@npmcli/run-script/lib/node-gyp-bin/go README.md ion-test..token--c /git git rev-�� HEAD 4171bb75..HEAD 64/bin/node token-test.txt(http block)/usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv --count 521435cd..HEAD $name) { hasDiscussionsEnabled } } README.md ion-test..token-config _modules/.bin/giuser.name git rev-�� HEAD 521435cd tnet/tools/git token-test.txt ings.cjs k/node_modules/./home/REDACTED/work/gh-aw/gh-aw/.github/workflows 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 --show-toplevel x_amd64/vet /usr/bin/git -json fg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/lib/git-core/git-remote-https ortcfg fg x_amd64/link /usr/lib/git-core/git-remote-https(http block)/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv -e -f /home/REDACTED/.cargo/bin/bash -- unsafe /node_modules/.b--show-toplevel bash --no�� --noprofile go /opt/hostedtoolcache/go/1.25.8/x64/bin/bash k/gh-aw/gh-aw st/dist/workers/rev-parse ml bash(http block)/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv --git-dir go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/lib/git-core/git e-analyzer.md GO111MODULE 64/bin/go /usr/lib/git-core/git(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 --show-toplevel x_amd64/compile /usr/bin/git -json GO111MODULE x_amd64/compile git -C /tmp/gh-aw-test-runs/20260422-044401-33052/test-1559533316 l 64/pkg/tool/linux_amd64/compile 01 GO111MODULE 64/bin/go 64/pkg/tool/linux_amd64/compile(http block)Agent-Logs-Url: REDACTED 64/pkg/tool/linux_amd64/link remote.origin.urgit 7a714ef2b2a60e12rev-parse k.yml 64/pkg/tool/linux_amd64/link` (http block)
Agent-Logs-Url: REDACTED ache/go/1.25.8/x64/bin/go l 7a714ef2b2a60e12rev-parse 64/pkg/tool/linu--show-toplevel git` (http block)