Skip to content

fix(dev-admin): a version check that did not happen says so - #127

Closed
MichaelC8E wants to merge 1 commit into
tina4stack:v3from
MichaelC8E:fix/version-check-does-not-claim-up-to-date-when-offline
Closed

MichaelC8E wants to merge 1 commit into
tina4stack:v3from
MichaelC8E:fix/version-check-does-not-claim-up-to-date-when-offline

Conversation

@MichaelC8E

Copy link
Copy Markdown
Contributor

The problem

The dev-admin version check answers 200 OK with latest == current when it never reached the
package registry at all. The toolbar reads that as a match and renders a green
"Latest: vX — You are up to date!".

So a developer several releases behind, on a machine with no route out, is told the opposite of
the truth. The handler initialises latest = current, wraps the registry call in a catch-all,
and returns the placeholder on any failure — offline, DNS failure, timeout, a non-2xx, or an
answer it could not read a version out of.

The client is already correct and unreachable: the toolbar's .catch writes
Could not check for updates (offline?), and it can never fire, because the server turned the
failure into a success.

The fix

latest is null when the check could not be made, and an error string says why. The toolbar
branches on the null before comparing versions, so a failed check reads as a failed check.

Reaching the registry and failing to read a version out of the answer takes the same path — it
is the same claim by another route.

Reproducing it

Pin the framework behind the latest release, then ask /__dev/api/version-check twice — once
with the network up, once with it unreachable. The two answers should differ.

Before:

online:  {"current":"3.13.125","latest":"3.13.134"}
offline: {"current":"3.13.125","latest":"3.13.125"}   <- green "You are up to date!"

After:

online:  {"current":"3.13.134","latest":"3.13.134"}
offline: {"current":"3.13.134","latest":null,"error":"..."}

Tests

Three new tests in tests/test_dev_admin.py, and one replaced: the existing
test_version_check_handler called PyPI for real and asserted latest was always a string —
the defect written down as an expectation. It now stubs urllib.request.urlopen.

Full suite on this branch: 5229 passed, with the same 14 failures the untouched base has (live
services not running locally). Each piece of the fix was reverted on its own to confirm it turns
a test red by itself.

The endpoint answered HTTP 200 with latest == current whenever the call to
PyPI failed, and the toolbar renders that as a green "Latest: vX — You are up
to date!". A developer several releases behind, on a machine with no route
out, was told the opposite of the truth.

The toolbar already had the right message for this — "Could not check for
updates (offline?)" on fetch's .catch — and could never reach it, because the
server turned the failure into a success.

latest is now None when the check could not be made, with a short error beside
it, and the toolbar reads that before it compares versions. Reaching PyPI and
getting a body with no version in it goes down the same path: it is the same
lie by another route.

The old test called PyPI for real and asserted latest was always a string,
which is the bug written down as an expectation. It is now stubbed, and joined
by the offline case, the unreadable-answer case, and one that holds the client
to branching on the null before the up-to-date comparison.

Verified end to end: a project pinned to 3.13.125 answers latest 3.13.131 with
the network up, and {"latest": null, "error": ...} with the registry
unreachable. It used to answer 3.13.125 both times.
@MichaelC8E

Copy link
Copy Markdown
Contributor Author

Closing this for now — not because of anything in the diff.

v3 CI in this repo is currently red on its own push runs, at the exact commit this branch is cut from, and this PR inherits those failures. Rather than leave a red PR sitting in the queue, I'll hold it and open it again once v3 is green.

The branch stays where it is; nothing here changes.

@MichaelC8E MichaelC8E closed this Sep 7, 2026
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.

1 participant