pubkey/rxdb · error · RxError

QU10

QU10

Error message

        RxDB Error-Code: ${message}.
        Hint: Error messages are not included in RxDB core to reduce build size.
        To show the full error messages and to ensure that you do not make any mistakes when using RxDB,
        use the dev-mode plugin when you are in development mode: https://rxdb.info/dev-mode.html?console=error
        
Find out more about this error here: https://rxdb.info/errors.html?console=errors#QU10 
Still stuck? Ask in the RxDB Discord: https://rxdb.info/chat 

What it means

findOne().remove(throwIfMissing) throws QU10 when no document matches the query and throwIfMissing was set. It tells you the document you asked to delete does not exist. Without throwIfMissing, remove() just returns null for a missing document.

Source

Thrown at src/rx-query.ts:528

            if (result.error.length > 0) {
                throw rxStorageWriteErrorToRxError(result.error[0]);
            } else {
                return result.success as any;
            }
        } else if (docs instanceof Map) {
            const docsArray = [...docs.values()];
            const result = await this.collection.bulkRemove(docsArray as any);
            if (result.error.length > 0) {
                throw rxStorageWriteErrorToRxError(result.error[0]);
            }
            const resultMap = new Map();
            result.success.forEach((doc: any) => resultMap.set(doc.primary, doc));
            return resultMap as any;
        } else {
            // findOne() can return null when no document matches
            if (!docs) {
                if (throwIfMissing) {
                    throw newRxError('QU10', {
                        collection: this.collection.name,
                        query: this.mangoQuery,
                        op: this.op
                    });
                }
                return null as any;
            }
            return (docs as any).remove();
        }
    }
    incrementalRemove(): Promise<RxQueryResult> {
        return runQueryUpdateFunction(
            this.asRxQuery,
            (doc) => doc.incrementalRemove(),
        );
    }

View on GitHub (pinned to af6fb65f94)

Solutions

  1. Call remove() without arguments and handle the null return if absence is acceptable.
  2. Check existence with findOne().exec() before calling remove(true).
  3. Treat QU10 as an already-deleted success in idempotent flows.

Example fix

// before
await collection.findOne(id).remove(true);
// after (idempotent delete)
const doc = await collection.findOne(id).exec();
if (doc) { await doc.remove(); }
Defensive patterns

Strategy: try-catch

Validate before calling

const doc = await collection.findOne(id).exec();
if (doc) { await doc.remove(); } // otherwise treat as already deleted

Type guard

function isMissingDocument(err: any): boolean {
  return err?.code === 'QU10';
}

Try / catch

try {
  await collection.findOne(id).remove(true);
} catch (err) {
  if (err.code === 'QU10') {
    // already deleted, idempotent success
  } else { throw err; }
}

Prevention

When it happens

Trigger: collection.findOne(id).remove(true) after the document was already deleted; deleting by a selector that no longer matches (e.g. status changed); a race where another client removed the doc between lookup and remove.

Common situations: Delete-then-retry flows that hit the second delete; idempotent cleanup jobs processing stale id lists; tests asserting existence that no longer holds after replication pulls deletes.

Related errors


AI-assisted analysis of pubkey/rxdb@af6fb65f94 (2026-08-31). Data as JSON: /api/errors/c1996f7f9d02345f. Report an issue: GitHub.