pubkey/rxdb · error · RxError

QU9

QU9

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#${message} 
Still stuck? Ask in the RxDB Discord: https://rxdb.info/chat 

What it means

RxQuery.exec(throwIfMissing) with a truthy argument is only valid on findOne() queries. When the query's op is 'find' (or any op other than 'findOne'), RxDB throws QU9 because there is no meaningful 'missing document' semantics for a multi-result query. RxDB core throws error codes without full messages to keep the production build small; the dev-mode plugin fills in the text.

Source

Thrown at src/rx-query.ts:373

         */
        if (this.collection._changeEventBuffer.getCounter() !== counterBefore) {
            await promiseWait(20);
            return this._execOverDatabase(rerunCount + 1);
        }

        return result;
    }

    /**
     * Execute the query
     * To have an easier implementations,
     * just subscribe and use the first result
     */
    public exec(throwIfMissing: true): Promise<RxDocument<RxDocType, OrmMethods, Reactivity>>;
    public exec(): Promise<RxQueryResult>;
    public async exec(throwIfMissing?: boolean): Promise<any> {
        if (throwIfMissing && this.op !== 'findOne') {
            throw newRxError('QU9', {
                collection: this.collection.name,
                query: this.mangoQuery,
                op: this.op
            });
        }

        /**
         * run _ensureEqual() here,
         * this will make sure that errors in the query which throw inside of the RxStorage,
         * will be thrown at this execution context and not in the background.
         */
        await _ensureEqual(this as any);
        const useResult = ensureNotFalsy(this._result);
        return useResult.getValue(throwIfMissing);
    }


View on GitHub (pinned to af6fb65f94)

Solutions

  1. Call exec() without arguments (or with false) on find() queries and check the returned array yourself.
  2. If you need the missing-document error, switch the query to findOne() before calling exec(true).
  3. Add the dev-mode plugin in development to see the full QU9 message.

Example fix

// before
const docs = await collection.find(selector).exec(true);
// after
const docs = await collection.find(selector).exec();
// or, if you really want throw-if-missing:
const doc = await collection.findOne(selector).exec(true);
Defensive patterns

Strategy: validation

Validate before calling

if (query.op !== 'findOne') {
  const docs = await query.exec(); // never pass true to a find() query
} else {
  const doc = await query.exec(true);
}

Type guard

function isFindOneQuery(q: RxQuery<any, any>): boolean {
  return (q as any).op === 'findOne';
}

Try / catch

try {
  const doc = await query.exec(true);
} catch (err) {
  if (err.code === 'QU9') {
    const doc = await query.exec();
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling myQuery.exec(true) on a query created with .find() instead of .findOne(); copying findOne-style code onto a find() query; a helper that accepts a query and always passes throwIfMissing=true.

Common situations: Refactoring a findOne query to find to get all results while keeping exec(true); wrapping generic query-execution utilities; TypeScript types usually catch this, but plain JS or any-typed code paths do not.

Related errors


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