Skip to content

fix(mattermost): remove substring auth misclassification + escalate genuine WS auth failures - #85157

Merged
teknium1 merged 3 commits into
mainfrom
salvage/80489-mattermost-ws-auth
Aug 13, 2026
Merged

fix(mattermost): remove substring auth misclassification + escalate genuine WS auth failures#85157
teknium1 merged 3 commits into
mainfrom
salvage/80489-mattermost-ws-auth

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

A transient error whose message merely contains "401" no longer permanently kills the Mattermost WebSocket listener — and a genuine auth rejection now escalates through the fatal-error hook instead of dying silently while is_connected() keeps reporting healthy.

Salvages #80489 by @steveonjava (authorship preserved via cherry-pick, both commits) onto current main, plus our follow-up closing the zombie half.

Changes

From #80489 (cherry-picked):

  • Remove the substring fallback in _ws_loop() that classified any exception mentioning "401"/"403"/"unauthorized" as a permanent failure (proxy error bodies, 502 pages quoting an upstream 401, etc.). The structured WSServerHandshakeError + status in {401, 403} check — the only true auth rejection — is kept
  • Regression tests + a 142-line adversarial verifier-probe file (403 boundary, non-auth handshake statuses, "unauthorized" substring variant, multi-retry)

Follow-ups (ours):

  • The genuine 401/403 branch still exited with a bare return: _running stayed True, the gateway was never told — the zombie-listener half of the bug (same class as fix(gateway): classify terminal adapter connect failures + escalate long-lived retry loops (OOF-156) #85049's connect-path fixes). It now sets a non-retryable mattermost_auth_error with token guidance and notifies the gateway fatal handler
  • pytest.importorskip("aiohttp") in the probe file — its module-level import aiohttp crashed collection in envs without the optional dep

Validation

Check Result
test_ws_auth_retry.py + verifier probe (venv with aiohttp) 8/8 pass
same files in repo test venv (no aiohttp) probe skips cleanly, no collection error
ruff on touched files clean
Pre-push stale-base gate 0 behind main; diff = 3 files, only ours

Closes #80489. Related: #35645 keeps its API-classification/lock/attachment scope; its substring-escalation half is superseded here.

Infographic

Mattermost WebSocket auth classification

steveonjava and others added 3 commits August 13, 2026 01:39
The WS reconnect loop had a fallback check that looked for "401", "403",
or "unauthorized" as substrings anywhere in an exception's string form.
A transient error whose message happens to contain those digits (a proxy
body, a stack trace, anything) got treated as a permanent auth failure
and stopped reconnection for good.

I removed the substring fallback and kept only the structured check:
aiohttp.WSServerHandshakeError with status in {401, 403}. That's the only
signal that reliably means the server rejected our credentials.

Added two regression tests: one proving a transient error containing
"401" in its text still retries, and one confirming the existing
_closing early-return path is untouched by the removal.
…ify fix

Independent-verifier boundary probes for commit fdd1a11ac5, covering
cases the implementer's regression tests did not exercise:
- WSServerHandshakeError(status=403) also stops the loop (only 401 tested)
- WSServerHandshakeError(status=500) does NOT stop the loop (structured
  check must not over-match on type alone)
- transient error containing the word 'unauthorized' (not digit substring)
  now retries correctly
- 5 consecutive transient errors all retry, not just the first

Verified these 2nd/4th tests fail against the pre-fix baseline commit
(01a1037) and pass against the fix (fdd1a11ac5), confirming they
have real signal.
…error hook

Follow-up to the salvaged #80489 substring-fallback removal: the
structured 401/403 branch still exited with a bare return, leaving
_running True — dead listener, healthy-looking is_connected(), gateway
never told (the zombie half of the bug, OOF-156 class). It now sets a
non-retryable mattermost_auth_error with token guidance and notifies
the gateway fatal handler.

Also: pytest.importorskip for aiohttp in the verifier probe file
(module-level import crashed collection in envs without the optional
dep), and probe fixtures updated for the escalation attributes.
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on bd99426 — fix(mattermost): escalate genuine WS auth failures through t

⚠️ Warnings

OSV vulnerability scan · View job

3 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 3m29s vs 7m48s (-55.3%). 13 job(s) slower, 9 faster, 2 unchanged.

  • Python tests / Run tests slice 6/12: +45.0s
  • Python tests / Run tests slice 9/12: +36.0s
  • OSV scan / Scan lockfiles / osv-scan: +32.0s
  • Python tests / Run tests slice 10/12: -26.0s
  • Python tests / Run tests slice 7/12: -24.0s

@teknium1
teknium1 merged commit f4749a7 into main Aug 13, 2026
45 checks passed
@teknium1
teknium1 deleted the salvage/80489-mattermost-ws-auth branch August 13, 2026 08:51
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.

2 participants