Session Canvas/Docs

Troubleshooting

Symptom → cause → fix, for the problems people actually hit.

Signing in

  • Your production URL isn’t in Supabase’s allow-list. Add https://your-app.example.com/auth/callback under Authentication → URL Configuration → Redirect URLs.
  • Admin sign-in links only go to invited team members — an unknown address gets the same “check your inbox” message but no email, by design.

No email ever arrives

  • RESEND_API_KEY isn’t set — mail is being logged to the server console instead of sent (in local dev, that console is where portal sign-in links live). See Environment variables.
  • Key set but still nothing in production: check EMAIL_FROM — without it the sandbox sender only delivers to the Resend account owner.

The admin shows “You’re signed in as a speaker”

Your browser holds a speaker-portal session (you opened a portal link — the demo token does this). Click Leave speaker mode to clear it and return to the admin.

Files and uploads

Uploads fail on a fresh deployment

  • The storage buckets don’t exist yet — run pnpm tsx scripts/setup-storage.ts once per environment.
  • DIRECT_URL or SUPABASE_SERVICE_ROLE_KEY is missing — both are validated on the upload path even when the rest of the app works.

Public pages and embeds

The schedule embed or feed is empty

  • Only sessions that are published and scheduled (start and end time set) appear publicly. Check the agenda’s publish toggle and the unscheduled tray.
  • A saved embed that’s been disabled returns 404 on purpose — re-enable it under Widgets & Embeds.
  • Changes can take up to ~5 minutes to appear on embeds (~1 minute on feeds).

Scheduled jobs

Airtable stopped syncing / reminders stopped sending in production

  • CRON_SECRET is unset — in production the cron endpoints answer 401 and the jobs silently stop. Set it on the project; Vercel then authenticates its own cron calls automatically.
  • For Airtable specifically: check Settings → Airtable — a Reconnect needed badge means the stored grant expired or ENCRYPTION_KEY changed, and the run log there reports not_configured events.

Things that are by design

  • Accepting a proposal doesn’t email the speaker. Decision emails are always sent deliberately from Communications.
  • Speakers can’t see scores or the shortlist. The portal shows shortlisted and unreviewed proposals identically as “Under review”.
  • CFP drafts live on the speaker’s device. They aren’t synced to the server, so organizers can’t see them and another browser won’t have them.
  • The speaker portal serves one event — the deployment’s original event. Multi-event support in the portal is on the roadmap.
  • The demo portal token expires 7 days after seeding — re-run pnpm db:seed.
  • Disconnecting Airtable is permanent-until-reconnected: the event won’t silently fall back to the deployment-wide AIRTABLE_* variables.

Still stuck?

Open an issue on GitHub with the symptom, what you expected, and any server log lines (they’re prefixed — [email:mocked], [airtable], [cron:…] — and never contain full recipient addresses).