Sync sessions are rejected with an unknown error when a client's v1 schema has no recordVersions
️: 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.getMigrationsSince → computeMigrationsSince, 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
- 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.
Source: tldraw/tldraw