RocketChat / RocketChat/Rocket.Chat

Response schemas are open (typia): API returns undeclared fields (type drift)

Open
#42,086 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug
Dominant language
TypeScript
Stars
46.1k
Forks
13.9k
Avg merge
3d 3h
Merged PRs (30d)
130

Description

Summary

REST response validation passes today only because typia (9.7.2) emits open object schemas (additionalProperties absent). Every response object schema is open, so responses that carry fields the declared types don't model slip through silently. This is latent type debt: the API returns fields its own @rocket.chat/core-typings types do not declare.

It surfaced while evaluating TypeScript 7 (typia 13, which emits closed objects — additionalProperties: false). Under closed schemas the server rejects its own real responses at boot/validation time. This issue tracks reconciling that drift; it is independent of the TS7 work (TS7 is being unblocked separately by keeping typia's schema generation on the current toolchain).

Evidence

Measured in one of 17 API/UI test shards (all failed the same way once objects were closed):

path undeclared field type
/message text IMessage
/message parseUrls IMessage
/message editedAt IMessage
/messages[] score IMessage (search)
/result/updated[] text syncMessages
/commands[] result command
(root) success response envelope
(root) isClientSafe me
/integration(s) (field) IIntegration

Proof the schemas are open today (typia 9, on develop):

core-typings dist: 0 object schemas closed / 284 open
IMessage.additionalProperties === undefined  (open)
IMessage schema declares: text=false parseUrls=false editedAt=false score=false

So chat.postMessage / chat.sendMessage responses ship text, parseUrls, editedAt; chat.search ships score — none modeled by IMessage, all currently accepted only because the schema is open.

Scope (three classes of work)

  1. Undeclared/leaked fields — the bulk. ~6 types / ~8 fields in one shard → extrapolating the full response surface, dozens of endpoints and an estimated 20–50 (type, field) reconciliation points. Each needs a per-endpoint decision: add the field to the type, model a response-superset type, or stop the handler from leaking it. Same character as the endpoint-contract drift (ARCH-2200 / TS7-W3).
  2. Nullable rendering — systemic. T | null currently produces a oneOf that can match more than one branch (passingSchemas: 0,1, e.g. calendar-events.info /event/meetingUrl). Affects potentially every nullable field across all ~196 component types. Needs its own pass (may be a single normalization or per-case).
  3. Response envelopesuccess / isClientSafe appearing at the validated root; a handful, structural (validation composition, not a type field).

Why now

Nothing in response validation changed. typia 9 emits open objects → drift hidden. typia 13 emits closed objects → drift exposed. typia 13 is arguably more correct; the type base is what's incomplete. Same failure mode as ARCH-2200 (endpoint contract) and the TS7 merged-interface enforcement — a stricter tool revealing pre-existing type debt.

Not in scope

Fixing this is not required to adopt TS7. TS7 is unblocked by keeping typia schema generation on the current (TS5) toolchain for the two typia packages. This issue is the separate, genuine cleanup of response-type accuracy.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the API/UI test shards and the generated @rocket.chat/core-typings schemas, reproducing the listed response-validation failures for /message, /messages[], /result/updated[], /commands[], and the response root. Review the undeclared fields, nullable rendering cases, and response envelope fields. Done means the response types and validation behavior reconcile the reported drift without failures under closed schemas.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend-api-design
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.