Skip to content

Raw-exec consumers that surface error.message as an operator-facing detail now read the composed DATABASE_ERROR sentence — read cause there (follow-up to #16019) #16657

Description

@os-musk

Filed unassigned by the #16019 dev (PR #16650, patch round), at the contract reviewer's disposition: "filed, not noted". ⛔ No label, no severity asserted — routing is triage's. Not a leak and not a classification change; an operator-diagnostics regression on a named set of sites, with the remedy known.

What changed upstream

Since PR #16650, SqlDriver.execute() — the raw-SQL seam every migration probe, backfill and cli db clean runs through — declares a backend refusal instead of letting the dialect's error object out: code: DATABASE_ERROR, status: 500, a COMPOSED message ("The database refused to run a raw statement. …"), the dialect error whole under a NON-ENUMERABLE cause, and the statement plus dialect text written to the driver's warn sink (default console.warn) before composing. TursoDriver remote mode declares the same way.

⇒ Every consumer that embedded error.message of a raw-exec failure into an operator-facing record now embeds the composed sentence. The dialect's words are one cause away (and printed one line earlier on any default deployment), but the structured detail / error field an operator reads has lost them.

The sites — measured on origin/main 4fe00b80e7 (line numbers by grep -n, re-derive by symbol)

  • packages/metadata-protocol/src/migrations/runtime-index-preflight.ts:298return unreadable(error instanceof Error ? error.message : String(error)) (the per-probe detail); :337seamFailure = error instanceof Error ? error.message : String(error).
  • packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts:1184 (detail), :1259 (status: 'absent', detail: (e as Error).message), :1305 (organizationProbeError), :1388 / :1414 / :1447 ({ error: (e as Error).message } result records).
  • packages/metadata-protocol/src/migrations/partial-index-probe.ts:37 and :359 — the module note says this module "hands back a classified status plus the driver's own text", and the comment at :359 says "detail is the OPERATOR-facing text and stays the driver's own prose". Both now state the opposite of what happens: detail is the composed sentence. The classification itself is unaffected (classifyIndexFailure is cause-following).
  • packages/cli/src/commands/db/clean.ts:115printError(VACUUM failed for ${file}: ${error?.message ?? error}); the dialect text still reaches the console through the driver's default warn sink, printed first, so this one is cosmetic.
  • The four migration result records that store err.message after a raw-exec failure: packages/metadata/src/migrations/{migrate-env-id-to-project-id,migrate-sys-notification-to-event,drop-projection-tables,migrate-project-id-to-environment-id}.ts.

Correction after the delta review of PR #16650 (card #16019, comment 5574921392): the first version of this card also listed metadata-protocol/src/migrations/overlay-index.ts, sys-setting-identity-index.ts and protocol.ts (around :5654-5670). Those three are swallow-only catches — a bare catch { fallback = 'refused'; }, catch { return false; }, a bare catch { — and store no err.message; they are dropped, and the list above is the verified set.

Positive control for the census: remote-transport.ts's no such column sniff (2 hits) fires on the same expressions; the reviewer's independent survey S1/S8 on PR #16650 enumerated the same raw-exec set.

Remedy

At each site, derive the operator-facing text from the cause chain when the thrown error declares DATABASE_ERROR — one small helper (walk cause to the first node whose message is not the composed sentence, depth-bounded like matchesDriverError) — and correct the two partial-index-probe.ts comments to say what the detail now carries. ⛔ Do not read the dialect text back into error.message at the driver: the composed message is the disclosure clause of the raw-path envelope (PR #16650's driver docblock says why), and these sites are operator surfaces that can read cause directly.

Evidence

Related

#16019 · PR #16650 · #8931 / PR #9273 (the same envelope on the typed read exits, where no such operator record existed)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions