toeverything/AFFiNE · warning · Error
No metadata provided
Error message
No metadata provided
What it means
Plain Error thrown by updateDocMeta when called with meta.title === undefined. The method's only supported field is title, so an input without it is a no-op at best and almost always a caller bug. It is a generic Error (not BadRequest), so it will surface as 500 unless wrapped — a defect worth fixing in the library.
Source
Thrown at packages/backend/server/src/core/doc/writer.ts:216
return { success: true };
}
/**
* Updates document metadata (currently title only).
*
* @param workspaceId - The workspace ID
* @param docId - The document ID to update
* @param meta - Metadata updates
* @param editorId - Optional editor ID for tracking
*/
async updateDocMeta(
workspaceId: string,
docId: string,
meta: { title?: string },
editorId?: string
): Promise<UpdateDocResult> {
if (meta.title === undefined) {
throw new Error('No metadata provided');
}
this.logger.debug(`Updating doc meta ${docId} in workspace ${workspaceId}`);
const existingDoc = await this.storage.getDoc(workspaceId, docId);
if (!existingDoc?.bin) {
throw new NotFoundException(`Document ${docId} not found`);
}
const rootDoc = await this.storage.getDoc(workspaceId, workspaceId);
if (!rootDoc?.bin) {
throw new NotFoundException(
`Workspace ${workspaceId} not found or has no root document`
);
}
const existingBinary = Buffer.isBuffer(existingDoc.bin)
? existingDoc.binView on GitHub (pinned to 26c515e050)
Solutions
- On the caller, only invoke updateDocMeta when meta.title !== undefined; skip the call entirely otherwise.
- If title is the only field, prefer a dedicated setTitle method or require title as a positional arg so the type system rejects `{}`.
- In the library, replace `throw new Error('No metadata provided')` with `throw new BadRequest('No metadata provided')` so it returns 400, not 500.
Example fix
// before
async updateDocMeta(workspaceId, docId, meta: { title?: string }, editorId?) {
if (meta.title === undefined) {
throw new Error('No metadata provided');
}
...
}
// after — make the contract explicit and return 400
async updateDocMeta(workspaceId, docId, title: string, editorId?) {
if (typeof title !== 'string' || title.length === 0) {
throw new BadRequest('title is required for updateDocMeta');
}
...
} Defensive patterns
Strategy: validation
Validate before calling
function buildMetaUpdate(input: { title?: string }) {
if (input.title === undefined) return null; // nothing to do — skip the call
return { title: input.title };
}
const meta = buildMetaUpdate(form);
if (meta) await writer.updateDocMeta(ws, doc, meta); Type guard
function hasMetaTitle(meta: unknown): meta is { title: string } {
return typeof (meta as any)?.title === 'string';
} Try / catch
if (hasMetaTitle(form)) {
await writer.updateDocMeta(ws, doc, { title: form.title });
} // else skip — never trigger the error Prevention
- Skip the call entirely when title is undefined instead of relying on the throw.
- Prefer a positional `title: string` parameter to make the contract unambiguous.
- In the library, upgrade the throw to BadRequest so it returns 400.
When it happens
Trigger: Caller passes `{}` or omits title, e.g. `updateDocMeta(ws, doc, {})` or `updateDocMeta(ws, doc, { someOtherField: x })`. Often a frontend that builds the meta object conditionally and ends up with no keys.
Common situations: Frontend form where the title field was unchanged and the build-meta helper skipped it. A refactor that renamed the field but left old callers. Batch job iterating over objects that happen to have no title key.
Related errors
- Can not find the version to rollback to.
- Workspace ${workspaceId} not found or has no root document
- Document ${docId} not found
- selfhost license key is required
- bad_request
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/f99d1037c0fdefa2.
Report an issue: GitHub.