Skip to content

latest-prerelease lookup strands users on 1.0.81-9: releases share created_at, so GitHub ranks -10 below -2 and the first listed prerelease is chosen #4605

Closed

Description

@ms-jb

latest-prerelease lookup strands users on 1.0.81-9

Summary

copilot update prerelease refuses to advance from 1.0.81-9 to 1.0.81-10, reporting the older build as the latest available release:

> copilot --no-auto-update update prerelease
Checking for updates...
Checking GitHub for the latest release...
No update needed, current version is 1.0.81-9, fetched latest release is v1.0.81-9

At the time of that run, v1.0.81-10 had been published for ~1.5 hours and was not a draft:

> gh api repos/github/copilot-cli/releases/tags/v1.0.81-10 \
    --jq '"tag=\(.tag_name) draft=\(.draft) prerelease=\(.prerelease) published=\(.published_at) assets=\(.assets|length)"'
tag=v1.0.81-10 draft=false prerelease=true published=2026-08-25T21:15:43Z assets=20

Root cause

Every 1.0.81-N release shares an identical created_at, so GitHub's list endpoint cannot order them by creation time and falls back to a lexicographic tiebreak. "10" sorts below "2", so -10 lands in the middle of the list rather than at the top:

> gh api "repos/github/copilot-cli/releases?per_page=12" \
    --jq '.[] | "\(.tag_name)  created=\(.created_at)  published=\(.published_at)"'
v1.0.81-9   created=2026-08-14T20:20:00Z  published=2026-08-24T17:42:32Z
v1.0.81-8   created=2026-08-14T20:20:00Z  published=2026-08-23T14:46:46Z
v1.0.81-7   created=2026-08-14T20:20:00Z  published=2026-08-21T18:39:24Z
v1.0.81-6   created=2026-08-14T20:20:00Z  published=2026-08-20T17:59:54Z
v1.0.81-5   created=2026-08-14T20:20:00Z  published=2026-08-19T23:16:31Z
v1.0.81-4   created=2026-08-14T20:20:00Z  published=2026-08-19T18:23:39Z
v1.0.81-3   created=2026-08-14T20:20:00Z  published=2026-08-19T08:46:57Z
v1.0.81-2   created=2026-08-14T20:20:00Z  published=2026-08-19T04:28:01Z
v1.0.81-10  created=2026-08-14T20:20:00Z  published=2026-08-25T21:15:43Z   <-- newest, ranked 9th
v1.0.81-1   created=2026-08-14T20:20:00Z  published=2026-08-18T18:30:50Z
v1.0.81-0   created=2026-08-14T20:20:00Z  published=2026-08-14T23:47:01Z
v1.0.80     created=2026-08-10T16:19:17Z  published=2026-08-14T02:28:39Z

The selection appears to take the first prerelease in that default ordering. In app.js, the update routine logs the message above from:

if (nR.lte(s.tag_name, Kh())) {
  let u = `No update needed, current version is ${Kh()}, fetched latest release is ${s.tag_name}`;
  ...
}

where s originates from lx() → uht("latest-prerelease", ...) → native githubLookupRelease(...).

Worth emphasising: the comparison is not the bug. nR.lte is semver-aware and ranks 1.0.81-9 < 1.0.81-10 correctly (numeric prerelease identifiers compare numerically). The wrong value is the release that gets fetched. Since GitHub exposes no "latest prerelease" endpoint (/releases/latest returns v1.0.80, the newest stable), the native lookup must enumerate — and it trusts list order.

Impact

Any prerelease line that reaches -10 strands every user on -9 for the remainder of that line. This is not self-correcting: it persists until a new stable or minor version is published. It affects both explicit copilot update prerelease and the automatic startup update check, on all platforms.

Steps to reproduce

  1. Be on 1.0.81-9 (or install it).
  2. Run copilot --no-auto-update update prerelease.
  3. Observe No update needed ... fetched latest release is v1.0.81-9, despite v1.0.81-10 being published.

The --no-auto-update prefix matters for a clean repro: without it, the startup auto-update check inflates the reported running version, so a plain copilot update prerelease compares against an already-elevated value and no-ops for a second, unrelated reason.

Suggested fix

Don't rely on list ordering. After enumerating non-draft releases, select the maximum by semver (or by published_at) before comparing against the running version. A one-line jq equivalent that resolves correctly today:

[.[] | select(.draft == false)] | sort_by(.published_at) | reverse | .[0].tag_name

Separately, giving each release a distinct created_at at publish time would remove the ambiguity at the source, though the client-side sort is the durable fix.

Workaround

Download the release asset for the desired tag directly and replace the binary, bypassing the update check entirely.

Environment

  • Windows 11, win32-x64
  • Copilot CLI 1.0.81-9 (standalone exe), attempting to reach 1.0.81-10

Activity

  1. added
    area:installationInstalling, updating, versioning, PATH setup, and binary distribution
    and removed on Aug 26, 2026
  2. ms-jb commented on Aug 26, 2026

    @ms-jb
    Author

    This resolved for me on v1.0.81-12

  3. copilot-cli-bot commented on Sep 23, 2026

    @copilot-cli-bot

    This appears to be resolved as of GitHub Copilot CLI v1.0.88. Please update to that release or a newer stable version. We're closing this as completed. If it still happens, please comment with your version and reproduction steps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:installationInstalling, updating, versioning, PATH setup, and binary distribution

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions