Repository navigation
Description
Describe the bug
When you have a workflow run, that creates an artifact and you rerun this workflow, then you have two artifacts (2 attempts).
Using gh run download <run-id> --name artifact-name, the artifact from the first attempt is downloaded, which is not the latest artifact.
Affected version
2.83.2
Steps to reproduce the behavior
- Type this 'GH_DEBUG=api gh run download 20775770442 --repo pmd/pmd --name pmd-regression-tester'
- View the output, it downloads the artifact https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281/zip - which is the artifacts from the first attempt of the workflow run
Expected vs actual behavior
Expected: It should download the artifact from the second attempt of the workflow run: https://api.github.com/repos/pmd/pmd/actions/artifacts/5047215209/zip
Actual: It downloaded the artifact from the first attempt of the workflow run: https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281/zip
Workaround
Instead of the "gh run download" command, you can use this:
download_url=$(gh api \
"/repos/$OWNER/$REPO/actions/runs/$RUN_ID/artifacts?name=$ARTIFACT_NAME" \
--jq '.artifacts|sort_by(.created_at)|.[-1]|.archive_download_url' \
)
curl -L \
-H "Authorization: Bearer $GH_TOKEN" \
--output artifact.zip \
$download_url
unzip artifact.zip
rm artifact.zipThis sorts the artifacts by "created_at" timestamp and chooses the last one.
Logs
Details
GH_DEBUG=api gh run download 20775770442 --repo pmd/pmd --name pmd-regression-tester
* Request at 2026-01-07 13:30:01.253226536 +0100 CET m=+0.169792185
* Request to https://api.github.com/repos/pmd/pmd/actions/runs/20775770442/artifacts?per_page=100
> GET /repos/pmd/pmd/actions/runs/20775770442/artifacts?per_page=100 HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ...
> Content-Type: application/json; charset=utf-8
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.83.2
⣻< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Cache-Control: private, max-age=60, s-maxage=60
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Wed, 07 Jan 2026 12:30:01 GMT
< Etag: W/"e88a52f7ab5fa4e26bd7b1823d72705aafe994d79ef35945a9996fc28c99226f"
< Github-Authentication-Token-Expiration: 2026-02-09 09:54:11 +0100
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Github-Permissions: actions=read
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Api-Version-Selected: 2022-11-28
< X-Github-Media-Type: github.v3; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: EB1F:1776B2:4392FC6:3D33E34:695E51C9
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 4999
< X-Ratelimit-Reset: 1767792601
< X-Ratelimit-Resource: core
< X-Ratelimit-Used: 1
< X-Xss-Protection: 0
{
"total_count": 7,
"artifacts": [
{
"id": 5046971645,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ2OTcxNjQ1",
"name": "compile-artifact",
"size_in_bytes": 31712152,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046971645",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046971645/zip",
"expired": false,
"digest": "sha256:7f060bcd4173aee923a2f18cef32575660485b8a1a0df98a0235d7de2f412068",
"created_at": "2026-01-07T08:53:09Z",
"updated_at": "2026-01-07T08:53:09Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5046971843,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ2OTcxODQz",
"name": "staging-repository",
"size_in_bytes": 8364820,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046971843",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046971843/zip",
"expired": false,
"digest": "sha256:c88e407a82262308fd1cb121e4abdf6b181e6d04839e2d90f0ed5fba1dc9fb52",
"created_at": "2026-01-07T08:53:11Z",
"updated_at": "2026-01-07T08:53:11Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5046972269,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ2OTcyMjY5",
"name": "dist-artifact",
"size_in_bytes": 86209640,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046972269",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046972269/zip",
"expired": false,
"digest": "sha256:7f542b5ca1021f0934cea0cdb451bd10a1d48b1ee99f3b90ef83fbcd4bfbbc19",
"created_at": "2026-01-07T08:53:14Z",
"updated_at": "2026-01-07T08:53:14Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5046997887,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ2OTk3ODg3",
"name": "docs-artifact",
"size_in_bytes": 9531535,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046997887",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5046997887/zip",
"expired": false,
"digest": "sha256:303f44e45e3bad8245d8a30fa12ac2a71e07ce7e2e23cfa4229cd4bf7e34688d",
"created_at": "2026-01-07T08:56:04Z",
"updated_at": "2026-01-07T08:56:04Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5047033823,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ3MDMzODIz",
"name": "javadocs-artifact",
"size_in_bytes": 19882752,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047033823",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047033823/zip",
"expired": false,
"digest": "sha256:7cf6b24f3e0d3a6bc01736f42949b3c17e766229869f0cffa70a06c4742c5153",
"created_at": "2026-01-07T09:00:09Z",
"updated_at": "2026-01-07T09:00:09Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5047083281,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ3MDgzMjgx",
"name": "pmd-regression-tester",
"size_in_bytes": 348,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281/zip",
"expired": false,
"digest": "sha256:a88bf576727865790739e17380b7c5447cedb376876f35b8462982be2a5ecca8",
"created_at": "2026-01-07T09:05:47Z",
"updated_at": "2026-01-07T09:05:47Z",
"expires_at": "2026-04-07T08:49:42Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
},
{
"id": 5047215209,
"node_id": "MDg6QXJ0aWZhY3Q1MDQ3MjE1MjA5",
"name": "pmd-regression-tester",
"size_in_bytes": 312,
"url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047215209",
"archive_download_url": "https://api.github.com/repos/pmd/pmd/actions/artifacts/5047215209/zip",
"expired": false,
"digest": "sha256:2a5dc18badea9c17f6d7a33573b56784609b3e357369084aba06f7a105ecbec4",
"created_at": "2026-01-07T09:19:23Z",
"updated_at": "2026-01-07T09:19:23Z",
"expires_at": "2026-04-07T09:18:47Z",
"workflow_run": {
"id": 20775770442,
"repository_id": 4992906,
"head_repository_id": 4992906,
"head_branch": "dependabot/maven/scalameta.version-4.14.4",
"head_sha": "c74a38eec86530a91dae98dc3de5b61ae556aa55"
}
}
]
}
* Request took 315.646026ms
* Request at 2026-01-07 13:30:01.570352359 +0100 CET m=+0.486917998
* Request to https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281/zip
> GET /repos/pmd/pmd/actions/artifacts/5047083281/zip HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ...
> Content-Type: application/json; charset=utf-8
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.83.2
⣻< HTTP/2.0 302 Found
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Content-Length: 0
< Content-Security-Policy: default-src 'none'
< Content-Type: text/html;charset=utf-8
< Date: Wed, 07 Jan 2026 12:30:01 GMT
< Location: https://productionresultssa8.blob.core.windows.net/actions-results/f7e160b1-337d-43e1-9a06-e582cc2049a5/workflow-job-run-85f2ffda-a5d8-59a2-b022-2720c75e89c1/artifacts/320b47470b5efc53d6aabbf132e1c041d7dad8aa50ab2cb6ef7bfe2f874c8b3a.zip?rscd=attachment%3B+filename%3D%22pmd-regression-tester.zip%22&se=2026-01-07T12%3A40%3A01Z&sig=1HHFeiqosmSuXP3o94EESFojnJrnTinXYuQvt9arxGk%3D&ske=2026-01-07T21%3A18%3A57Z&skoid=ca7593d4-ee42-46cd-af88-8b886a2f84eb&sks=b&skt=2026-01-07T09%3A18%3A57Z&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skv=2025-11-05&sp=r&spr=https&sr=b&st=2026-01-07T12%3A29%3A56Z&sv=2025-11-05
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Api-Version-Selected: 2022-11-28
< X-Github-Request-Id: EB1F:1776B2:439318C:3D33FF8:695E51C9
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 4998
< X-Ratelimit-Reset: 1767792601
< X-Ratelimit-Resource: core
< X-Ratelimit-Used: 2
< X-Xss-Protection: 0
* Request took 299.224323ms
* Request at 2026-01-07 13:30:01.869640176 +0100 CET m=+0.786205809
* Request to https://productionresultssa8.blob.core.windows.net/actions-results/f7e160b1-337d-43e1-9a06-e582cc2049a5/workflow-job-run-85f2ffda-a5d8-59a2-b022-2720c75e89c1/artifacts/320b47470b5efc53d6aabbf132e1c041d7dad8aa50ab2cb6ef7bfe2f874c8b3a.zip?rscd=attachment%3B+filename%3D%22pmd-regression-tester.zip%22&se=2026-01-07T12%3A40%3A01Z&sig=1HHFeiqosmSuXP3o94EESFojnJrnTinXYuQvt9arxGk%3D&ske=2026-01-07T21%3A18%3A57Z&skoid=ca7593d4-ee42-46cd-af88-8b886a2f84eb&sks=b&skt=2026-01-07T09%3A18%3A57Z&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skv=2025-11-05&sp=r&spr=https&sr=b&st=2026-01-07T12%3A29%3A56Z&sv=2025-11-05
> GET /actions-results/f7e160b1-337d-43e1-9a06-e582cc2049a5/workflow-job-run-85f2ffda-a5d8-59a2-b022-2720c75e89c1/artifacts/320b47470b5efc53d6aabbf132e1c041d7dad8aa50ab2cb6ef7bfe2f874c8b3a.zip?rscd=attachment%3B+filename%3D%22pmd-regression-tester.zip%22&se=2026-01-07T12%3A40%3A01Z&sig=1HHFeiqosmSuXP3o94EESFojnJrnTinXYuQvt9arxGk%3D&ske=2026-01-07T21%3A18%3A57Z&skoid=ca7593d4-ee42-46cd-af88-8b886a2f84eb&sks=b&skt=2026-01-07T09%3A18%3A57Z&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skv=2025-11-05&sp=r&spr=https&sr=b&st=2026-01-07T12%3A29%3A56Z&sv=2025-11-05
> Host: productionresultssa8.blob.core.windows.net
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Content-Type: application/json; charset=utf-8
> Referer: https://api.github.com/repos/pmd/pmd/actions/artifacts/5047083281/zip
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.83.2
⣯< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: x-ms-request-id,Server,x-ms-version,Content-Type,ETag,Last-Modified,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,Content-Disposition,x-ms-server-encrypted,Accept-Ranges,Content-Length,Date,Transfer-Encoding
< Content-Disposition: attachment; filename="pmd-regression-tester.zip"
< Content-Length: 348
< Content-Type: zip
< Date: Wed, 07 Jan 2026 12:30:02 GMT
< Etag: "0x8DE4DCBF23E85C6"
< Last-Modified: Wed, 07 Jan 2026 09:05:47 GMT
< Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
< X-Ms-Blob-Type: BlockBlob
< X-Ms-Creation-Time: Wed, 07 Jan 2026 09:05:47 GMT
< X-Ms-Lease-State: available
< X-Ms-Lease-Status: unlocked
< X-Ms-Request-Id: 1ce1129d-b01e-00ce-15d1-7f36b3000000
< X-Ms-Server-Encrypted: true
< X-Ms-Version: 2025-11-05
* Request took 455.557872ms
Activity
jsoref commentedon Jan 7, 2026
I came here to file this. My guess is that github changed the sort order of the endpoint.
Note that the workaround will almost certainly fail if you do enough reruns to trigger pagination, or if your jobs generate lots of artifacts.
jsoref commentedon Jan 7, 2026
Fwiw, afaict the array limit is 30 which means that if you have more than 30 artifacts in the results, you're going to hit pagination:
jsoref commentedon Jan 7, 2026
In fact, it's much better (for my use case at least) to ask for
per_page=1:{ "total_count": 333, "artifacts": [ { "id": 5037147613, "node_id": "MDg6QXJ0aWZhY3Q1MDM3MTQ3NjEz", "name": "check-spelling-comment", "size_in_bytes": 46486, "url": "https://api.github.com/repos/check-spelling-sandbox/MeshCore/actions/artifacts/5037147613", "archive_download_url": "https://api.github.com/repos/check-spelling-sandbox/MeshCore/actions/artifacts/5037147613/zip", "expired": false, "digest": "sha256:a8c226d11d54f9507d24394fceb5e02b9ea2ccd27f615e1d706884527101e2eb", "created_at": "2026-01-06T13:47:12Z", "updated_at": "2026-01-06T13:47:12Z", "expires_at": "2026-04-06T13:46:23Z", "workflow_run": { "id": 20750207409, "repository_id": 1128664294, "head_repository_id": 1128664294, "head_branch": "spell-check-with-spelling", "head_sha": "5aefd5dd6ed4512a2e6b2b4470988bbe06c0319c" } } ] }And then the
last(from theLink:header) page:{ "total_count": 333, "artifacts": [ { "id": 5053199227, "node_id": "MDg6QXJ0aWZhY3Q1MDUzMTk5MjI3", "name": "check-spelling-comment", "size_in_bytes": 11047, "url": "https://api.github.com/repos/check-spelling-sandbox/MeshCore/actions/artifacts/5053199227", "archive_download_url": "https://api.github.com/repos/check-spelling-sandbox/MeshCore/actions/artifacts/5053199227/zip", "expired": false, "digest": "sha256:61311ca3cbfee5254a13209aee4b5f448d18c7b6e6edc962fd810c43d53a78c6", "created_at": "2026-01-07T18:09:59Z", "updated_at": "2026-01-07T18:09:59Z", "expires_at": "2026-04-07T18:09:35Z", "workflow_run": { "id": 20750207409, "repository_id": 1128664294, "head_repository_id": 1128664294, "head_branch": "spell-check-with-spelling", "head_sha": "5aefd5dd6ed4512a2e6b2b4470988bbe06c0319c" } } ] }adangel commentedon Jan 8, 2026
Yes, if you have many repeated runs of your workflow (aka attempts), then you might hit the paging problem. In order to sort the artifacts client-side, you need to have them all. I see, you have re-run your workflow 334 times...
Note, that you can only upload an artifact with a specific name once ("it is no longer possible to upload to the same named Artifact multiple times" -> https://github.com/actions/upload-artifact?tab=readme-ov-file#breaking-changes). The only way to have multiple artifacts with the same name seems to be now when you re-run a workflow.
For my use case, I don't rerun the workflows that often, so the default page size of 30 is ok. You could try to query a single very big page (e.g. per_page=1000), but there's probably also an undocumented upper limit. Your approach using per_page=1 (which is for one named artifact exactly one workflow run attempt) and using the "last" link, sound reasonable. However, you'll depend on the sort order, that github implements. If the last is not the latest, then this won't work.
babakks commentedon Jan 8, 2026
Thanks for the investigation here, @adangel and @jsoref! 🙏
I'm curious what would you get if you omit the run ID, @adangel. 🤔
Can you please run this and share the output (redact where needed)?
The reason I'm asking this is that when the run ID is missing,
ghuses a different API endpoint, and I'm curious to see how that endpoint sort the entries.jsoref commentedon Jan 8, 2026
Fwiw, I've now replaced my use of
gh run download.Of course, I now will need to rely on the endpoint sort order being oldest to newest and I'm hoping to ship with this commit shortly (and I release once or twice a year).
babakks commentedon Jan 8, 2026
My bad, nevermind. You folks have already checked that route. 🏅
Seems like
ghdoesn't expect to see colliding artifact names in the same run. But it's possible with retry attempts.However, I have to check internally to see if there has been any changes to the endpoint that returns the list of artifacts for a single run.
jsoref commentedon Jan 8, 2026
(I might add a check to my code to ensure it picks the newest between the first and the last page in the case that github changes the sort order. I'll talk w/ @nebuk89 about this today -- didn't happen)
jsoref commentedon Jan 8, 2026
Fwiw, the api appears to say the max page size is 100:
... Conveniently I've already far exceeded that. -- I was planning to stop closer to 1000, but it was a slow process and I stopped and determined I'd already proved my point and didn't feel a need to continue.
For a different, but related endpoint, the oldest item is on the last page:
https://github.com/check-spelling/check-spelling/blame/0b27d64c0ff97ddad604b38de45a92e722637dbf/t/apply.t#L77-L99
And, yes, I've added some code to my gh-run-download to check to see which is newer (first or last) and favor the new one. I'm also fixed
apply.plto properly get the latest version for reruns.Fwiw, while there's a
lastheader in the examples above, I had some trouble dealing w/ that header in apply.pl (it looked like I ran into a case where that header wasn't present), so for that, I just guess that i can get to the nth object by going to the nth page of 1 per page pages -- it saves some parsing as I already have to parse the json of the first page to get the object on that page. And, of course, if github decides to make the list randomly sorted, then, I give up.I also ran into some fun cases where GitHub's servers sent out pointers to domains that have been out of use for over a decade.
Note that I run regression testing on
apply.pldaily, so if other behaviors change in this stuff, I should be notified. I'm tempted to add a test to assert the order of reruns, but, that's actually pretty annoying to do. I think I'd need to have a workflow that runs (probably on a schedule) that uploads an artifact, and then have a workflow file withon:/workflow_run:/completedfor that workflow which in turn triggers a rerun for that workflow (but only once).4 remaining items
[-]gh run download doesn't download latest artifact[/-][+]`gh run download` doesn't download latest artifact[/+][-]`gh run download` doesn't download latest artifact[/-][+]`gh run download` doesn't download latest artifact from latest attempt[/+]github-actions commentedon Mar 9, 2026
Thank you for your issue! We have categorized it as an enhancement (feature or improvement) request, and it has been added to our backlog. In doing so, we are not committing to implementing this feature at this time, but, we will consider it for future releases based on community feedback and our own product roadmap.
Unless you see the help wantedContributions welcome
label, we are not currently looking for external contributions for this feature.
If you come across this issue and would like to see it implemented, please add a thumbs up! This will help us prioritize the feature. Please only comment if you have additional information or viewpoints to contribute.
williammartin commentedon Mar 10, 2026
https://docs.github.com/en/rest/actions/artifacts?apiVersion=2022-11-28#list-workflow-run-artifacts now contains a
directionquery parameter. Note that we currently support the 4 most recent GHES versions, so this won't be a complete solution for now.jsoref commentedon Mar 10, 2026
@williammartin is there a way to determine whether the
directionparameter was honored? If so, that'd ensure that for the FPT instance, it's one query + one retrieval. If not, I think it's still two queries + one retrieval.williammartin commentedon Mar 10, 2026
I don't think the API will tell us this, so we can either do a heuristic check, or probably add something to the feature detector to do a version check based on the host being targeted (if GHES). Some prior art:
cli/internal/featuredetection/feature_detection.go
Lines 307 to 315 in 19864b9
jsoref commentedon Mar 10, 2026
That appears to require a trip to
/meta. I don't think it's worth it. It's simpler to just send a query for first + last and compare. Once GHES supports direction, the code to get last + compare can be dropped.docs(eng): CAP-01-ATTEST-READER-01 repair - duplicate same-name attes…