pubkey/rxdb · error · RxError
SNH
SNH
Error message
RxDB Error-Code: SNH. 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
What it means
getSortComparator in src/rx-query-helper.ts throws the SNH ('should never happen') error when the query has no sort property. A sort comparator can only be built from a query that carries a sort definition, so a sort-less query reaching this internal helper indicates an inconsistent query state.
Source
Thrown at src/rx-query-helper.ts:193
normalizedMangoQuery.sort = normalizedMangoQuery.sort.slice(0);
normalizedMangoQuery.sort.push({ [primaryKey]: 'asc' } as any);
}
}
return normalizedMangoQuery;
}
/**
* Returns the sort-comparator,
* which is able to sort documents in the same way
* a query over the db would do.
*/
export function getSortComparator<RxDocType>(
_schema: RxJsonSchema<RxDocumentData<RxDocType>>,
query: FilledMangoQuery<RxDocType>
): DeterministicSortComparator<RxDocType> {
if (!query.sort) {
throw newRxError('SNH', { query });
}
const sortParts: {
key: string;
direction: MangoQuerySortDirection;
getValueFn: ObjectPathMonadFunction<RxDocType>;
}[] = [];
query.sort.forEach(sortBlock => {
const key = Object.keys(sortBlock)[0];
const direction = Object.values(sortBlock)[0];
sortParts.push({
key,
direction,
getValueFn: objectPathMonad(key)
});
});
const fun: DeterministicSortComparator<RxDocType> = (a: RxDocType, b: RxDocType) => {
for (let i = 0; i < sortParts.length; ++i) {
const sortPart = sortParts[i];View on GitHub (pinned to af6fb65f94)
Solutions
- Ensure the query has a sort array before calling getSortComparator; fill it with the primary key sort as default.
- Use RxDB's query normalization (fillWithQueryDefaults or the collection's query filling) so sort is always present.
- If your query intentionally has no sort, do not request a sort comparator; skip sort-related processing in your pipeline.
Example fix
// before
const cmp = getSortComparator(schema, { selector: { age: { $gt: 0 } } });
// after
const query = { selector: { age: { $gt: 0 } }, sort: [{ age: 'asc' }] };
const cmp = getSortComparator(schema, query); Defensive patterns
Strategy: validation
Validate before calling
if (!query.sort) {
throw new Error('getSortComparator requires a filled query with sort');
}
const cmp = getSortComparator(schema, query); Type guard
function hasSort<RxDocType>(q: FilledMangoQuery<RxDocType>): q is FilledMangoQuery<RxDocType> & { sort: MangoQuerySortPart<RxDocType>[] } {
return Array.isArray(q.sort);
} Try / catch
try {
const cmp = getSortComparator(schema, query);
} catch (err) {
if (err?.code === 'SNH') {
return getSortComparator(schema, { ...query, sort: [{ id: 'asc' }] });
}
throw err;
} Prevention
- Always pass queries through RxDB's default-filling before low-level helpers.
- Add a unit test asserting every query your pipeline builds has a sort array.
- Treat SNH errors as bugs in your query construction, not user errors.
When it happens
Trigger: Calling getSortComparator(schema, query) (directly or via useSortComparator/sortComparator helpers) with a FilledMangoQuery whose sort field is undefined or null.
Common situations: Building custom storage implementations or query pipelines that pass a raw user query without filling defaults; custom RxStorage plugins or query-optimizer code that construct PreparedQuery inputs manually.
Related errors
AI-assisted analysis of pubkey/rxdb@af6fb65f94 (2026-08-31).
Data as JSON: /api/errors/30236ab1cd3eaae9.
Report an issue: GitHub.