Skip to content

fix(aw): Issue Arborist - re-apply curl REST API workaround for DIFC proxy#8573

Merged
Evangelink merged 1 commit into
mainfrom
dev/amauryleve/fix-issue-arborist-difc-proxy
May 25, 2026
Merged

fix(aw): Issue Arborist - re-apply curl REST API workaround for DIFC proxy#8573
Evangelink merged 1 commit into
mainfrom
dev/amauryleve/fix-issue-arborist-difc-proxy

Conversation

@Evangelink
Copy link
Copy Markdown
Member

Fixes #8571.

The Fetch issues data step in .github/workflows/issue-arborist.md still fails under the DIFC proxy even with gh-aw-mcpg v0.3.17 — the version that was supposed to resolve the /meta block per githubnext/agentics#339.

The most recent failed run (https://github.com/microsoft/testfx/actions/runs/26406407163) surfaced a different, but still gh CLI-induced, error:

⬇ Downloading the last 100 open issues (excluding sub-issues)...
malformed version: 
##[error]Process completed with exit code 1.

So PR #8550 (which reverted #8507's workaround in anticipation of the upstream mcpg fix) was premature. This PR re-applies the exact same curl + REST API workaround that was previously introduced in #8185 and re-applied in #8507. The compiled .lock.yml is regenerated with gh aw v0.75.0 compile --strict.

The agent prompt is unchanged because the curl pipeline normalizes the JSON shape to match what gh issue list --json would return (uppercased state etc.), so downstream jq queries in the prompt continue to work as-is.

The gh issue list invocation still fails under the DIFC proxy even with
gh-aw-mcpg v0.3.17 (the version was supposed to resolve the /meta block
per githubnext/agentics#339). The failed run at
https://github.com/microsoft/testfx/actions/runs/26406407163 surfaced a
different but related `malformed version:` error, so re-apply the
curl + REST API workaround that was introduced in #8185 / #8507 and
reverted in #8550.

Fixes #8571.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 15:56
Copy link
Copy Markdown
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

Re-applies the Issue Arborist “curl + GitHub Search REST API” workaround to fetch recent open issues without using gh issue list, avoiding DIFC proxy–related failures that are still occurring despite newer gh-aw-mcpg versions.

Changes:

  • Replace gh issue list with a curl call to ${{ github.api_url }}/search/issues, normalizing the REST payload via jq to match the expected gh --json shape.
  • Add GH_AW_ORIGINAL_GITHUB_API_URL env var to preserve the real API URL for the REST call.
  • Regenerate the compiled workflow lock file (--strict) to reflect the updated source workflow.
Show a summary per file
File Description
.github/workflows/issue-arborist.md Switches issue prefetching from gh to curl + REST search and normalizes output JSON for the agent prompt.
.github/workflows/issue-arborist.lock.yml Regenerated compiled workflow reflecting the updated fetch step and environment variables.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment on lines +55 to +57
"${GH_AW_ORIGINAL_GITHUB_API_URL}/search/issues" \
| jq '.items // [] | map({
number: .number,
@Evangelink Evangelink merged commit a303a44 into main May 25, 2026
14 checks passed
@Evangelink Evangelink deleted the dev/amauryleve/fix-issue-arborist-difc-proxy branch May 25, 2026 16:02
Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

Expert Review Summary

This PR re-applies a curl/REST API workaround for the Issue Arborist workflow to work around DIFC proxy compatibility issues with gh issue list.

# Dimension Verdict
1 Algorithmic Correctness 🔴 1 MAJOR
8 Defensive Coding at Boundaries 🔴 1 MAJOR

✅ 19/21 dimensions clean.

Issues Found

  • Algorithmic Correctness — Semantic mismatch: -parent-issue:*-is:sub-issue. The new query will include child issues that should be excluded, breaking the workflow's filtering contract.
  • Defensive Coding — Pipeline error handling: the || echo '[]' fallback only applies to curl, not the entire curl | jq pipeline. If jq fails (malformed JSON, HTML error page), the fallback doesn't execute and the workflow crashes.

Dimensions Not Applicable

The following dimensions were evaluated but do not apply to this workflow configuration change:

  • Threading & Concurrency (no shared mutable state)
  • Public API & Binary Compatibility (workflow files only)
  • Performance & Allocations (workflow execution, not hot path)
  • Cross-TFM Compatibility (no multi-targeting)
  • Resource & IDisposable Management (no .NET resources)
  • Localization & Resources (no user-facing strings)
  • Test Isolation, Assertion Quality, Flakiness, Test Completeness, Data-Driven Coverage (no test changes)
  • Naming & Conventions (bash/YAML, not C#)
  • Documentation Accuracy (extensive comments present)
  • Analyzer & Code Fix Quality (no analyzer changes)
  • IPC Wire Compatibility (no serialization protocol changes)

Clean Dimensions

  • Security & IPC Contract Safety — All inputs properly escaped, credentials handled securely, no injection vectors
  • Code Structure & Simplification — Appropriate structure for curl + jq pipeline
  • Build Infrastructure — Isolated workflow fix, no impact on build/test/release
  • Scope & PR Discipline — Single-purpose change, excellent cross-referencing (5+ related issues/PRs)

Note: The two MAJOR issues require fixes before merge. The semantic query mismatch could cause the arborist to process issues incorrectly, and the incomplete error handling will cause obscure failures when the API returns malformed responses.

Generated by Expert Code Review (on open) for issue #8573 · ● 3.3M

-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
--get \
--data-urlencode "q=repo:${GH_AW_GITHUB_REPOSITORY} is:issue is:open -is:sub-issue" \
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

[MAJOR] Algorithmic Correctness

Semantic mismatch in issue filtering query

The old query uses -parent-issue:* which excludes issues that have a parent-issue: custom field (i.e., issues that are children in a parent-child relationship).

The new query uses -is:sub-issue which excludes issues marked by GitHub's native sub-issue feature.

These are not equivalent.

Concrete failing scenario:

  1. Repository has Issue DeploymentItem should be implemented via Fx extensibility #100 (parent issue)
  2. Issue Removed Attribute from the namespace for DynamicDataAttribute #200 is linked as a child via the custom parent-issue: #100 field
  3. Old query (-parent-issue:*) → excludes Removed Attribute from the namespace for DynamicDataAttribute #200 (has parent)
  4. New query (-is:sub-issue) → includes Removed Attribute from the namespace for DynamicDataAttribute #200 (not marked as native sub-issue)
  5. The arborist now incorrectly processes Issue Removed Attribute from the namespace for DynamicDataAttribute #200 as a candidate for linking

Impact: Child issues that should be excluded will now be included, breaking the workflow's core filtering logic. The arborist may attempt to re-link issues that are already children, or create duplicate parent-child relationships.

Recommendation:
The search query should match the original intent. Options:

  • Use NOT "parent-issue" in:body if the parent relationship is tracked in issue bodies
  • Switch to GitHub's native sub-issue feature consistently (document the migration)
  • Use the GitHub GraphQL API directly with the same query structure as gh issue list

Note: The comment states this "re-applies the exact same workaround" from #8185 and #8507, but if those PRs had the same query mismatch, the filtering bug has been present since the original workaround.

milestone: (if .milestone != null then {title: .milestone.title} else null end),
assignees: [.assignees[] | {login: .login}]
})' \
> /tmp/gh-aw/issues-data/issues.json \
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

[MAJOR] Defensive Coding at Boundaries

jq parse failure not caught by fallback

The || echo '[]' fallback is chained only to curl, not to the entire curl | jq pipeline. If jq fails to parse the response (malformed JSON, HTML error page, network corruption), the fallback does NOT execute.

Concrete failing scenario:

  1. GitHub API returns HTTP 500 with an HTML error page (service outage, proxy error)
  2. curl succeeds (exit 0) and writes HTML to stdout
  3. jq attempts to parse HTML → parse error, exits 1
  4. The || echo '[]' fallback does not execute (it's only attached to curl)
  5. /tmp/gh-aw/issues-data/issues.json is empty or truncated
  6. The next line runs jq 'length' /tmp/gh-aw/issues-data/issues.jsoncrashes with parse error
  7. Workflow fails with obscure error instead of graceful degradation

Proof:

# Simulate malformed JSON
echo "not json" | jq '.items // []' > output.json || echo '[]' > output.json
# jq exits 1, but the || fallback doesn't fire because it's not part of the piped command

Recommendation:
The fallback must apply to the entire pipeline:

curl -s \
  -H "Authorization: Bearer ${GITHUB_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  --get \
  --data-urlencode "q=repo:${GH_AW_GITHUB_REPOSITORY} is:issue is:open -is:sub-issue" \
  --data-urlencode "sort=created" \
  --data-urlencode "order=desc" \
  --data-urlencode "per_page=100" \
  "${GH_AW_ORIGINAL_GITHUB_API_URL}/search/issues" \
  | jq '.items // [] | map({
      number: .number,
      title: .title,
      author: {login: .user.login},
      createdAt: .created_at,
      state: (.state | ascii_upcase),
      url: .html_url,
      body: .body,
      labels: [.labels[] | {name: .name}],
      updatedAt: .updated_at,
      closedAt: .closed_at,
      milestone: (if .milestone != null then {title: .milestone.title} else null end),
      assignees: [.assignees[] | {login: .login}]
    })' > /tmp/gh-aw/issues-data/issues.json \
  || echo '[]' > /tmp/gh-aw/issues-data/issues.json

Move the || echo '[]' to the end of the entire pipeline so it catches both curl and jq failures.

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.

[aw] Issue Arborist failed

2 participants