pubkey/rxdb · error · RxError
DOC3
DOC3
Error message
RxDB Error-Code: DOC3. 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
DOC3 is thrown when you try to observe a final (read-only) schema field via RxDocument.get$(path). Final fields cannot be modified, so their value can never change and an observable would never emit anything new; RxDB rejects the call to surface the mistake. This check only runs in dev mode.
Source
Thrown at src/rx-document.ts:150
/**
* returns observable of the value of the given path
*/
get$(this: RxDocument, path: string): Observable<any> {
if (overwritable.isDevMode()) {
if (path.includes('.item.')) {
throw newRxError('DOC1', {
path
});
}
if (path === this.primaryPath) {
throw newRxError('DOC2');
}
// final fields cannot be modified and so also not observed
if (this.collection.schema.finalFields.includes(path)) {
throw newRxError('DOC3', {
path
});
}
const schemaObj = getSchemaByObjectPath(
this.collection.schema.jsonSchema,
path
);
if (!schemaObj) {
throw newRxError('DOC4', {
path
});
}
}
return this.$
.pipe(View on GitHub (pinned to af6fb65f94)
Solutions
- Read the final field statically: const createdAt = doc.get('createdAt').
- Exclude final fields (this.collection.schema.finalFields) from any dynamic observation logic.
- If the value must change, remove final: true from the schema (requires a schema/migration rethink, not a code-only fix).
Example fix
// before
doc.get$('createdAt').subscribe(v => ...);
// after
const createdAt = doc.get('createdAt'); // final fields never change, no observation needed Defensive patterns
Strategy: validation
Validate before calling
function assertNotFinal(doc, path) {
if (doc.collection.schema.finalFields.includes(path)) {
throw new Error('Final field cannot be observed, read statically: ' + path);
}
} Type guard
function isMutableField(doc, path) {
return !doc.collection.schema.finalFields.includes(path);
} Try / catch
try {
obs = doc.get$(path);
} catch (err) {
if (String(err?.code) === 'DOC3') {
// final fields never change: emit the static value once
import('rxjs').then(({ of }) => obs = of(doc.get(path)));
} else {
throw err;
}
} Prevention
- Filter doc.collection.schema.finalFields out of dynamic observation paths.
- Read final fields (createdAt etc.) statically once.
- Only mark fields final: true when their value genuinely never changes.
- Keep the dev-mode plugin enabled while developing to catch this early.
When it happens
Trigger: Calling doc.get$() on a field defined with final: true in the RxJsonSchema, e.g. a createdAt timestamp, while the dev-mode plugin is active.
Common situations: Observing schema-internal fields like createdAt/updatedAt marked final; generic observation helpers that walk all schema properties including final ones; migrating schemas where a field newly became final.
Related errors
AI-assisted analysis of pubkey/rxdb@af6fb65f94 (2026-08-31).
Data as JSON: /api/errors/87f330c6e6f70d15.
Report an issue: GitHub.