toeverything/AFFiNE · error · InternalServerError
internal_server_error
internal_server_error
Error message
An internal error occurred.
What it means
The default branch of IndexerService.unwrap: the search operation returned an errorCode this server version does not map (anything other than workspace_denied, invalid_request, unsupported_query, provider_unavailable, permission_unavailable). It is thrown as a generic InternalServerError, hiding the raw code.
Source
Thrown at packages/backend/server/src/plugins/indexer/service.ts:153
doc.updatedByUser = users.get(doc.updatedByUserId);
}
return docs;
}
private unwrap<T>(output: SearchOperationOutput, workspaceId: string): T {
if (output.ok) return output.value as T;
switch (output.errorCode) {
case 'workspace_denied':
throw new SpaceAccessDenied({ spaceId: workspaceId });
case 'invalid_request':
case 'unsupported_query':
throw new InvalidIndexerInput({ reason: output.errorCode });
case 'provider_unavailable':
throw new SearchProviderNotFound();
case 'permission_unavailable':
throw new WorkspacePermissionNotFound({ spaceId: workspaceId });
default:
throw new InternalServerError();
}
}
}
View on GitHub (pinned to 591f874dad)
Solutions
- Log output.errorCode (or attach it to the thrown error) to identify which code is unmapped
- Deploy the search operation and the API server at aligned versions, together
- Add an explicit case in unwrap for the new errorCode once identified
Example fix
// before
default:
throw new InternalServerError();
// after: keep the raw code observable
default:
this.logger.error('unmapped indexer errorCode', output.errorCode);
throw new InternalServerError(); Defensive patterns
Strategy: fallback
Validate before calling
// pin search operation and API server versions together in deploy config assert(semverCompatible(serverVersion, searchWorkerVersion));
Try / catch
// catch the generic 500 and degrade, while logging for diagnosis
try {
return await indexerService.search(user, { workspaceId, query });
} catch (e) {
if (e instanceof InternalServerError) {
logger.error('indexer unmapped failure', { workspaceId, query });
return emptyResult(); // keep the editor usable without search
}
throw e;
} Prevention
- Deploy the search worker and the API server atomically to avoid errorCode version skew
- Log the raw SearchOperationOutput.errorCode at the boundary before mapping it
- Add a contract test enumerating every errorCode the worker can emit against unwrap's switch
When it happens
Trigger: A version-skewed search worker emits a new errorCode the API server's switch does not know, or an internal bug produces an unexpected code. The raw output.errorCode is the key diagnostic but is swallowed by the generic throw.
Common situations: Rolling deploys where the search/indexer operation is newer than the API server (or vice versa); new error codes added upstream without updating unwrap.
Related errors
- invalid_indexer_input
- search_provider_not_found
- workspace_permission_not_found
- space_access_denied
- ErrorCode.SelectionError
AI-assisted analysis of toeverything/AFFiNE@591f874dad (2026-08-21).
Data as JSON: /api/errors/267285a4d6157367.
Report an issue: GitHub.