#10105·tldraw

Sync sessions are rejected with an unknown error when a client's v1 schema has no recordVersions

Author: steveruizokCreated Aug 19, 2026Updated Sep 15, 2026
Labelssdk

️: Sentry TLDRAW-SYNC-3VT: TypeError: Cannot convert undefined or null to object in upgradeSchema while handling a client's connect request in the sync worker — 2 events.


When a client connects with a schema-version-1 serialized schema that is missing its record versions, upgrading the schema throws instead of returning an error result. The sync room catches the exception generically and rejects the session with an unknown error, when it should be rejected as a client-too-old / version mismatch like other unsupported schemas.

Expected behavior: a malformed or incomplete legacy schema is rejected cleanly with the version-mismatch reason, not by an exception.

Where

upgradeSchema in packages/store/src/lib/StoreSchema.ts validates schemaVersion but then iterates schema.recordVersions unguarded:

for (const [typeName, recordVersion] of Object.entries(schema.recordVersions)) {

Object.entries(undefined) throws the TypeError. The call reaches it from StoreSchema.getMigrationsSincecomputeMigrationsSince, which is what TLSyncRoom.handleConnectRequest calls on the client-supplied message.schema (packages/sync-core/src/lib/TLSyncRoom.ts). That path already handles a !migrations.ok result by rejecting with getVersionMismatchReason(...), so returning Result.err instead of throwing would route this case through the existing rejection path.

Sentry: TLDRAW-SYNC-3VT

Open questions

  1. Is there a known client that still sends schema-version-1 payloads, or can this be treated purely as defensive hardening? Awaiting answer.

Confidence: 85%, ready to get started.