bug: Todoist access tokens never refreshed — silent failure after expiration #74

Closed
opened 2026-04-16 15:24:28 +00:00 by alvis · 0 comments
Owner

Problem

integration_tokens table has refresh_token and expires_at columns, but no refresh logic exists anywhere. The OAuth exchange in integrations.ts:82 stores only the access_token — no refresh_token is captured (Todoist may not provide one, but expiration is still unhandled).

After the token expires, fetchTodoistTasks() gets a 401, returns cached/empty tasks, and the user silently gets no tips.

Fix

  1. Check expires_at before each Todoist API call
  2. If Todoist provides refresh tokens, implement refresh flow
  3. If not, surface a "reconnect" prompt to the user when token fails
  4. Log signals.integration.token_expired event for observability
## Problem `integration_tokens` table has `refresh_token` and `expires_at` columns, but no refresh logic exists anywhere. The OAuth exchange in `integrations.ts:82` stores only the `access_token` — no `refresh_token` is captured (Todoist may not provide one, but expiration is still unhandled). After the token expires, `fetchTodoistTasks()` gets a 401, returns cached/empty tasks, and the user silently gets no tips. ## Fix 1. Check `expires_at` before each Todoist API call 2. If Todoist provides refresh tokens, implement refresh flow 3. If not, surface a "reconnect" prompt to the user when token fails 4. Log `signals.integration.token_expired` event for observability
alvis added this to the M2 — AI tips + multi-source signals milestone 2026-04-16 15:24:28 +00:00
alvis closed this issue 2026-04-17 13:34:45 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alvis/oO#74