fix(routers): tolerate a missing user_router_models table on older databases

↗ view on GitHub · Amal · 2026-08-18 · cf00ee86

A deploy-before-migrate window used to 500 GET /user/profile and every
chat/title/tabular request, because the new router-selection read threw
and nothing downstream caught it.

WHY THIS MATTERS
Rolling deploys routinely run new application code against a database
that has not received the newest migration yet. This codebase already
plans for that: selectProfile has a whole fallback cascade for profile
columns that don't exist yet (42703 undefined_column). The router-models
read had no such tolerance, so the profile page and the assistant were
both bricked until 20260818_01 landed - the new feature's absence took
down old features.

HOW IT WORKS
getUserRouterModels now recognizes the two shapes a missing relation
takes on this stack - Postgres undefined_table (SQLSTATE 42P01) and
PostgREST's schema-cache miss (PGRST205 naming user_router_models, the
table-level analog of the 42703 column shape selectProfile checks) -
and returns an empty selection, warning once per process so operators
see the migration is outstanding. Every other error still throws:
fail-open is deliberately scoped to "the table does not exist yet",
not to arbitrary database failures.

Tests: routerModels.test.ts - both missing-table shapes resolve to []
(fail on the ported code, which rejects), and an unrelated error code
still rejects, pinning the narrow scope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repository open-legal-products/mike
Author Amal <mamalanand3@gmail.com>
Authored
Committed
Parents af64aca5
Stats 2 files changed , +76 , -1
Part of Harden model-router selection and failure handling

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-cf00ee86.md from inside the repo you want the change in.

⬇ Download capture-commit-cf00ee86.md