chadtmiller.com/knotless
git that lives in your Atmosphere account
An OAuth login is kept when refreshing it fails
MergedThis keeps a stored OAuth session when its refresh fails for any reason other than invalid_grant. ensure logs login refresh failed and returns the error instead of logging in with KNOTLESS_PASSWORD and saving that over the session. The check is the same one session::ended already makes (starts_with(oauth::INVALID_GRANT)), so the two paths agree on what counts as turned down. App-password sessions and invalid_grant still fall back to the password, as the body says. The new test covers the kept session with an unreachable token endpoint. The change file and both docs edits are there, and I found nothing that needs to change. I did not read the test or check results, only the diff and the surrounding session.rs.
One small note, not blocking: ensure on the unreachable-endpoint path and ended now log the same warning. If both run on one request you will see it twice, which is harmless.
The only change since my approval is in session::ensure. It tidies the login refresh failed warning by binding did and passing err directly. The fields are the same and the behaviour is unchanged. err is still used afterwards in the bail!. That works because tracing macros take field values by reference. I only read this diff and the surrounding session.rs, not the checks. My earlier approval stands.
8 passed, 2 skipped
What changes
When a stored OAuth login's refresh fails,
session::ensurenow keeps the OAuth session and returns the error, logging it aslogin refresh failed, instead of logging in withKNOTLESS_PASSWORDand saving that session over it. The password still stands in for a login the server has turned down (invalid_grant), and for an app-password session whose refresh fails.deploy/runner-host/README.mdand theKNOTLESS_PASSWORDrow indocs/reference/cli.mdsay so. The README also says what the failure looks like and what fixes it.Why
Since 03:26Z today, the runner on the runner host hasn't been able to check any private repository: group-host, forum, invite-test, private-runner-check and private-site-try. Every look at one fails with
getting a delegation token … InvalidToken (403): Scope does not permit reading at://…/space/…, and filing a check fails withScope does not permit update. Until 03:26 the log has no errors.Its OAuth session's refresh failed once, at about the time it expired, while its PDS (the spaces alpha) was answering other calls with 500s.
ensurethen logged in with the runner's app password and saved that session over the OAuth one. An app password gets no delegation tokens, and restarting doesn't help, because the OAuth session is gone. Nothing logged the refresh failure, so the log showed only what followed.How it was checked
session_refresh_and_fallbacksintests/library.rsstores an OAuth session whose token endpoint can't be reached. It checks thatensurefails with the refresh error and that the stored session is unchanged. The existing cases still hold: an app-password session whose refresh is refused falls back to the password, and with no session and no password,ensurefails. Everything else is left to CI.Shortcomings
This doesn't bring the runner's session back: it was overwritten at 03:26. The runner's account has to approve the bot login again at
https://runner.knotless.dev/oauth/bot?account=<handle>. Why the refresh failed in the first place isn't known. It wasn't logged, and from now on it will be.A CLI user whose OAuth refresh fails now gets an error until the refresh works, where before they were quietly logged in with their password, if they had set one.
🤖 Generated with Claude Code