bug(scheduler): discovery runs for connection-less users -> spurious token errors; + stale Dex-era orphan user #7

Open
opened 2026-06-09 17:42:20 +00:00 by mathias · 2 comments
Owner

CORRECTED (original framing was wrong)

The original report claimed an onboarded user's refresh token doesn't persist and that this blocks all second users. That is false. Ground-truth DB inspection:

  • Jonas's real account 29e6f18b (Authentik, subject = jonas.eiemarker@gmail.com, connected 2026-06-09 17:10) has an active YouTube connection and 255 videos discovered. Multi-user discovery works. His momentary "no videos" was a timing gap — the screenshot was taken ~4 min after connecting, before the next 2h scheduler pass ran. A manually-triggered pass populated his 255 videos. → the durable fix for that gap is #6 (trigger discovery on connect).

The ref not found error in the logs is a different, stale account, not Jonas.

The two real (lower-severity) issues

A. Scheduler runs discovery for connection-less users → spurious token errors

store.ListAllUsers (internal/adapters/store/identity.go:47) returns every user_identities row, and the scheduler builds a per-user runner for each — even users with no YouTube connection. That runner still attempts resolve youtube oauth token: youtube/<uid>/refresh_tokensecrets: ref not found, logged as a WARN every pass. Noise, and it actively misled this debug.

Fix: before running a user's discovery pass, skip users with no active video_connections row (or no resolvable token ref). Downgrade the genuine "connected but token missing" case to a clear, single signal rather than a recurring per-pass error.

B. Dex→Authentik left an orphan tapir user

user_identities has a stale row: subject CiQ…SBWxvY2Fs (decodes to a Dex local-connector subject, internal id 3a1c3159…) → user fef8adf1…, created 2026-06-07 (pre-migration), now with 0 connections, 0 videos. It's a leftover from the Dex era; the same human (if any) re-onboarded under a fresh Authentik identity, leaving the Dex users row orphaned.

Fix: audit user_identities for Dex-subject rows (the Ci… protobuf format vs Authentik's email/uuid subjects); decide per row: delete the empty orphan, or merge if it carries data. Confirm no active human has split data across a Dex account + an Authentik account. Generalises the cobalt-dingo subject-change lesson to tapir's own user table.

Net

Multi-user tapir is functional (proven: 255 videos for a second user). These are cleanup + a missing-token UX signal, not a blocker. Severity downgraded from the original.

## CORRECTED (original framing was wrong) The original report claimed an onboarded user's refresh token doesn't persist and that this blocks all second users. **That is false.** Ground-truth DB inspection: - **Jonas's real account `29e6f18b`** (Authentik, subject = `jonas.eiemarker@gmail.com`, connected 2026-06-09 17:10) has an **active** YouTube connection and **255 videos** discovered. Multi-user discovery works. His momentary "no videos" was a **timing gap** — the screenshot was taken ~4 min after connecting, before the next 2h scheduler pass ran. A manually-triggered pass populated his 255 videos. → the durable fix for that gap is #6 (trigger discovery on connect). The `ref not found` error in the logs is a **different, stale account**, not Jonas. ## The two real (lower-severity) issues ### A. Scheduler runs discovery for connection-less users → spurious token errors `store.ListAllUsers` (`internal/adapters/store/identity.go:47`) returns **every** `user_identities` row, and the scheduler builds a per-user runner for each — even users with **no YouTube connection**. That runner still attempts `resolve youtube oauth token: youtube/<uid>/refresh_token` → `secrets: ref not found`, logged as a WARN every pass. Noise, and it actively misled this debug. **Fix:** before running a user's discovery pass, skip users with no active `video_connections` row (or no resolvable token ref). Downgrade the genuine "connected but token missing" case to a clear, single signal rather than a recurring per-pass error. ### B. Dex→Authentik left an orphan tapir user `user_identities` has a stale row: subject `CiQ…SBWxvY2Fs` (decodes to a **Dex local-connector** subject, internal id `3a1c3159…`) → user `fef8adf1…`, created 2026-06-07 (pre-migration), now with **0 connections, 0 videos**. It's a leftover from the Dex era; the same human (if any) re-onboarded under a fresh Authentik identity, leaving the Dex `users` row orphaned. **Fix:** audit `user_identities` for Dex-subject rows (the `Ci…` protobuf format vs Authentik's email/uuid subjects); decide per row: delete the empty orphan, or merge if it carries data. Confirm no active human has split data across a Dex account + an Authentik account. Generalises the cobalt-dingo subject-change lesson to tapir's own user table. ## Net Multi-user tapir is **functional** (proven: 255 videos for a second user). These are cleanup + a missing-token UX signal, not a blocker. Severity downgraded from the original.
mathias changed title from bug(connect): 2nd user's YouTube connection has no usable refresh token — discovery fails ref-not-found to bug(scheduler): discovery runs for connection-less users -> spurious token errors; + stale Dex-era orphan user 2026-06-09 18:44:56 +00:00
Author
Owner

Part A donec5f556d on main.

runDiscoveryPass now calls ConnectionsForUser and skips users with no video connection before running their pass, so the scheduler no longer attempts a YouTube token for connection-less identities (e.g. the stale Dex-era orphan fef8adf1). TDD: TestDiscoveryPassSkipsUsersWithoutConnections (red→green); task check green (fmt/vet/lint/tests). No change to connected users. Deploys via CI → Flux.

Part B still open — clean up the orphan user_identities row (CiQ…SBWxvY2Fsfef8adf1, Dex local subject, 0 connections/0 videos) and audit for any other Dex-subject rows left by the Authentik migration. Leaving this issue open for B.

**Part A done** — `c5f556d` on `main`. `runDiscoveryPass` now calls `ConnectionsForUser` and **skips users with no video connection** before running their pass, so the scheduler no longer attempts a YouTube token for connection-less identities (e.g. the stale Dex-era orphan `fef8adf1`). TDD: `TestDiscoveryPassSkipsUsersWithoutConnections` (red→green); `task check` green (fmt/vet/lint/tests). No change to connected users. Deploys via CI → Flux. **Part B still open** — clean up the orphan `user_identities` row (`CiQ…SBWxvY2Fs` → `fef8adf1`, Dex local subject, 0 connections/0 videos) and audit for any other Dex-subject rows left by the Authentik migration. Leaving this issue open for B.
Author
Owner

Part A (skip discovery for connection-less users) shipped in v0.9.0 — deployed, verified live: zero fef8adf1 ref-not-found errors on the new pod. Part B (clean up the stale Dex-era orphan user_identities row) remains open. Related: #3 (a different orphan, 2b85ade1, with videos but no identity) — same cleanup theme, worth bundling.

Part A (skip discovery for connection-less users) shipped in v0.9.0 — deployed, verified live: zero fef8adf1 ref-not-found errors on the new pod. Part B (clean up the stale Dex-era orphan user_identities row) remains open. Related: #3 (a different orphan, 2b85ade1, with videos but no identity) — same cleanup theme, worth bundling.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/tapir#7