Skip to content

Fix: roll back meta document and storage instance when createRxCollection() fails in addCollections() - #9595

Open
pubkey wants to merge 2 commits into
masterfrom
claude/vigilant-newton-8rqsab-failed-collection-creation-leaves-meta-doc
Open

pubkey wants to merge 2 commits into
masterfrom
claude/vigilant-newton-8rqsab-failed-collection-creation-leaves-meta-doc

Conversation

@pubkey

@pubkey pubkey commented Nov 11, 2026

Copy link
Copy Markdown
Owner

This PR contains:

  • A BUGFIX

Describe the problem you have without this PR

addCollections() left the collection meta document and the storage instance behind when the creation of the collection failed after the storage instance was created (for example with COL17), so that adding the collection again with an adjusted schema threw DB6

Covers a failure inside createRxCollection() after the storage instance exists, for example COL17. pubkey/rxdb#9577 covers the case where the storage rejects the creation of the storage instance and changes the same block.

  • Not rolled back: a collection that has a meta document of a previous schema version. A failed migration can have written documents into the new storage instance.
  • Risk with multiInstance: when another tab adds the same collection at the same moment and succeeds while the creation in this tab fails, the rollback removes the storage instance and meta document that the other tab uses.
  • The test triggers the failure with a reserved static name, which the dev-mode plugin rejects with COL17.

Changed files:

  • orga/changelog/fix-failed-collection-creation-leaves-meta-document.json
  • src/rx-database.ts
  • test/unit/rx-database.test.ts

Test output without the fix

The changed test file run on the memory storage with src/ from master:

  20 passing (95ms)
  1 failing

  1) rx-database.test.ts
       .addCollections()
         positive
           should be able to add the collection with an adjusted schema after the first creation failed:
     RxError (DB6): 

Error message: RxDatabase.addCollections(): another instance created this collection with a different schema. Read this: https://rxdb.info/rx-schema.html?console=qa#faq
Error code: DB6
Cause: The schema hash does not match the schema stored in the internal database.
Fix: If you changed the schema, you must increment the version number. If not, check why the hash is different.
Docs: https://rxdb.info/rx-schema.html?console=errors&code=DB6#faq
Find out more about this error here: https://rxdb.info/errors.html?console=errors#DB6 
Still stuck? Ask in the RxDB Discord: https://rxdb.info/chat 

--------------------
Parameters:
database: "xvdeadxksr"
collection: "items"
previousSchemaHash: "e1db93378e0a3a31dfb44b89b834ed1fe7279e59b9d48ef6455999f00a4aebe8"
schemaHash: "f9d03b4eb5518c419ace2eafc1d744d2d3df5c01abc86b1750503837f298933b"
previousSchema: {
  "additionalProperties": false,
  "description": "describes a human being",
  "encrypted": [],
  "indexes": [
    [
      "_deleted",
      "firstName",
      "passportId"

Test output with the fix

39 passing (214ms)

Todos

  • Tests
  • Changelog

Assisted by

YES, CLAUDE CODE


Generated by Claude Code

@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

✅ Verify Test Reproduction: Tests FAILED without the fix (expected)

This confirms the changed tests correctly reproduce the bug that the source changes fix.

This workflow runs the changed tests without the source fix to verify they reproduce the bug.

Show output
...(truncated, showing last 200 of 1787 lines)
	    "lastName",
	    "passportId",
	    "_deleted",
	    "_rev",
	    "_meta",
	    "_attachments"
	  ],
	  "title": "human schema",
	  "type": "object",
	  "version": 0
	}
	schema: {
	  "title": "human schema",
	  "description": "changed",
	  "version": 0,
	  "keyCompression": false,
	  "primaryKey": "passportId",
	  "type": "object",
	  "properties": {
	    "passportId": {
	      "type": "string",
	      "maxLength": 100
	    },
	    "firstName": {
	      "type": "string",
	      "maxLength": 100
	    },
	    "lastName": {
	      "type": "string",
	      "maxLength": 100
	    },
	    "age": {
	      "description": "age in years",
	      "type": "integer",
	      "minimum": 0,
	      "maximum": 150,
	      "multipleOf": 1
	    }
	  },
	  "required": [
	    "firstName",
	    "lastName",
	    "passportId"
	  ],
	  "indexes": [
	    "firstName"
	  ]
	}
	
	    at newRxError (/home/runner/work/rxdb/rxdb/src/rx-error.ts:127:12 <- /tmp/_karma_webpack_rxdb_6071/commons.js:190691:10)
	    at /home/runner/work/rxdb/rxdb/src/rx-database.ts:483:41 <- /tmp/_karma_webpack_rxdb_6071/commons.js:189583:74
	    at async Promise.all (index 0)
	    at async RxDatabaseBase.addCollections (/home/runner/work/rxdb/rxdb/src/rx-database.ts:460:13 <- /tmp/_karma_webpack_rxdb_6071/commons.js:189563:7)
	    at async Context.<anonymous> (/home/runner/work/rxdb/rxdb/test/unit/rx-database.test.ts:432:37 <- /tmp/_karma_webpack_rxdb_6071/commons.js:222370:27)


Chrome Headless 156.0.0.0 (Linux 0.0.0): Executed 410 of 1449�[31m (1 FAILED)�[39m (10.955 secs / 10.048 secs)
�[31mTOTAL: 1 FAILED, 409 SUCCESS�[39m


�[31m1) should be able to add the collection with an adjusted schema after the first creation failed
�[39m�[31m     rx-database.test.ts .addCollections() positive
�[39m�[90m     RxError (DB6): 

Error message: RxDatabase.addCollections(): another instance created this collection with a different schema. Read this: https://rxdb.info/rx-schema.html?console=qa#faq
Error code: DB6
Cause: The schema hash does not match the schema stored in the internal database.
Fix: If you changed the schema, you must increment the version number. If not, check why the hash is different.
Docs: https://rxdb.info/rx-schema.html?console=errors&code=DB6#faq
Find out more about this error here: https://rxdb.info/errors.html?console=errors#DB6 
Still stuck? Ask in the RxDB Discord: https://rxdb.info/chat 

--------------------
Parameters:
database: "tqenaylzwq"
collection: "items"
previousSchemaHash: "e1db93378e0a3a31dfb44b89b834ed1fe7279e59b9d48ef6455999f00a4aebe8"
schemaHash: "f9d03b4eb5518c419ace2eafc1d744d2d3df5c01abc86b1750503837f298933b"
previousSchema: {
  "additionalProperties": false,
  "description": "describes a human being",
  "encrypted": [],
  "indexes": [
    [
      "_deleted",
      "firstName",
      "passportId"
    ],
    [
      "_meta.lwt",
      "passportId"
    ]
  ],
  "keyCompression": false,
  "primaryKey": "passportId",
  "properties": {
    "_attachments": {
      "type": "object"
    },
    "_deleted": {
      "type": "boolean"
    },
    "_meta": {
      "additionalProperties": true,
      "properties": {
        "lwt": {
          "maximum": 1000000000000000,
          "minimum": 1,
          "multipleOf": 0.01,
          "type": "number"
        }
      },
      "required": [
        "lwt"
      ],
      "type": "object"
    },
    "_rev": {
      "minLength": 1,
      "type": "string"
    },
    "age": {
      "description": "age in years",
      "maximum": 150,
      "minimum": 0,
      "multipleOf": 1,
      "type": "integer"
    },
    "firstName": {
      "maxLength": 100,
      "type": "string"
    },
    "lastName": {
      "maxLength": 100,
      "type": "string"
    },
    "passportId": {
      "maxLength": 100,
      "type": "string"
    }
  },
  "required": [
    "firstName",
    "lastName",
    "passportId",
    "_deleted",
    "_rev",
    "_meta",
    "_attachments"
  ],
  "title": "human schema",
  "type": "object",
  "version": 0
}
schema: {
  "title": "human schema",
  "description": "changed",
  "version": 0,
  "keyCompression": false,
  "primaryKey": "passportId",
  "type": "object",
  "properties": {
    "passportId": {
      "type": "string",
      "maxLength": 100
    },
    "firstName": {
      "type": "string",
      "maxLength": 100
    },
    "lastName": {
      "type": "string",
      "maxLength": 100
    },
    "age": {
      "description": "age in years",
      "type": "integer",
      "minimum": 0,
      "maximum": 150,
      "multipleOf": 1
    }
  },
  "required": [
    "firstName",
    "lastName",
    "passportId"
  ],
  "indexes": [
    "firstName"
  ]
}

    at newRxError (/home/runner/work/rxdb/rxdb/src/rx-error.ts:127:12 <- /tmp/_karma_webpack_rxdb_6071/commons.js:190691:10)
    at /home/runner/work/rxdb/rxdb/src/rx-database.ts:483:41 <- /tmp/_karma_webpack_rxdb_6071/commons.js:189583:74
    at async Promise.all (index 0)
    at async RxDatabaseBase.addCollections (/home/runner/work/rxdb/rxdb/src/rx-database.ts:460:13 <- /tmp/_karma_webpack_rxdb_6071/commons.js:189563:7)
    at async Context.<anonymous> (/home/runner/work/rxdb/rxdb/test/unit/rx-database.test.ts:432:37 <- /tmp/_karma_webpack_rxdb_6071/commons.js:222370:27)
�[39m



View full workflow run

…tion() fails in addCollections()

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015P6w6hnnyVPXwotts6YQ2F
… closed before the rollback

The rollback of a failed collection creation is skipped when the database is closing or closed, and an error inside the rollback no longer replaces the creation error.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015P6w6hnnyVPXwotts6YQ2F
@pubkey
pubkey force-pushed the claude/vigilant-newton-8rqsab-failed-collection-creation-leaves-meta-doc branch from 5dbb5fb to 01ff046 Compare November 12, 2026 12:08

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants