Skip to content

external-datasource-federated-read: external-write refusal (ExternalWriteForbiddenError) leaks to the client as a bare 500 INTERNAL_ERROR #7739

Description

@huangyiirene

Symptom

A write to a read-only federated external object is correctly refused server-side — ExternalWriteForbiddenError names the datasource, its schemaMode, and both flags that would be required — but it reaches the client as a bare 500 INTERNAL_ERROR, indistinguishable from a crash. Nothing is applied (the remote table is byte-identical after the attempt). Same envelope-leak class as the auth bodyless-500s in #7663 and the earlier raw-TypeError leak in #7543 (and the 5xx driver-throw passthrough family #5437).

Root cause

ExternalWriteForbiddenError (defined in packages/spec/src/shared/external-errors.ts, thrown in packages/objectql/src/engine.ts) carries a stable code (EXTERNAL_ERROR_CODES.writeForbidden), but no REST/runtime error map references it: a git grep for writeForbidden / ExternalWriteForbidden / EXTERNAL_ERROR_CODES across packages/rest, packages/runtime, and packages/cli finds no mapping. So the error falls through the generic handler in packages/rest/src/rest-server.ts to 500 INTERNAL_ERROR instead of a 4xx envelope that carries the code and the refusal detail the error already computed.

Stale-premise check: present on origin/main (no external-error mapping exists in the rest/runtime layer).

Reproduction

  1. Boot with a read-only federated external object (schemaMode that forbids writes).
  2. POST /api/v1/data/<external_object> with any body.

Expected: a 4xx envelope with a stable code naming the write-forbidden refusal. Actual: 500 INTERNAL_ERROR with no code, indistinguishable from a crash, even though the server-side ExternalWriteForbiddenError was correct and nothing was applied.

Source

Extracted from the QA run #7690 (framework 92f26f7, console 09987b680).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions