toeverything/AFFiNE · error · QueryTooLong
query_too_long
query_too_long
Error message
Query is too long, max length is ${max}. What it means
The admin shared-link listing in WorkspaceAnalyticsModel clamps pagination values but hard-rejects overlong keywords: after trimming, a keyword longer than DOC_MEMBER_QUERY_MAX_LENGTH (255 characters, workspace-analytics.ts:20) throws QueryTooLong with that max.
Solutions
- Enforce maxlength=255 plus trim on the client search input before calling the API.
- Validate keyword length in the calling service and reject or truncate with a friendly message.
- Split very long searches into several narrower queries.
Example fix
// before
const result = await analytics.adminListSharedLinks({ keyword: longDump }); // > 255 chars -> QueryTooLong
// after
const keyword = longDump.trim().slice(0, 255);
const result = await analytics.adminListSharedLinks({ keyword }); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 255;
const keyword = rawKeyword.trim();
if (keyword.length > MAX) {
throw new ValidationError(`Query is too long, max length is ${MAX}.`);
}
const page = await analytics.adminListSharedLinks({ keyword }); Try / catch
try { await analytics.adminListSharedLinks({ keyword }); } catch (e) { if (e instanceof QueryTooLong) trimAndRetry(); else throw e; } Prevention
- Set maxlength=255 on all search inputs feeding these endpoints.
- Centralize the 255-char cap in a shared search-input component.
- Trim user input before length validation.
When it happens
Trigger: Calling the admin shared-links listing with options.keyword whose trimmed length exceeds 255 characters.
Common situations: Pasting a URL, stack trace, or a comma-separated list of emails into the search box; frontend search input without maxlength; e2e tests feeding synthetic long strings.
Related errors
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/d5c87c155508706b.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/models/workspace-analytics.ts:572
generatedAt: now,
};
}
async adminPaginateAllSharedLinks(
options: AdminAllSharedLinksOptions
): Promise<
OptionalTotalPaginated<AdminSharedLinkNode> & {
analyticsWindow: TimeWindowDto;
}
> {
const pagination: PaginationInput = {
...options.pagination,
first: Math.min(Math.max(options.pagination.first ?? 10, 1), 100),
offset: Math.max(options.pagination.offset ?? 0, 0),
};
const keyword = options.keyword?.trim();
if (keyword && keyword.length > DOC_MEMBER_QUERY_MAX_LENGTH) {
throw new QueryTooLong({ max: DOC_MEMBER_QUERY_MAX_LENGTH });
}
const includeTotal = options.includeTotal ?? false;
const orderBy = options.orderBy ?? 'UpdatedAtDesc';
const analyticsWindowDays = clampInt(
options.analyticsWindowDays,
1,
90,
DEFAULT_ANALYTICS_WINDOW_DAYS
);
const now = new Date();
const currentDay = startOfUtcDay(now);
const analyticsFrom = addUtcDays(currentDay, -(analyticsWindowDays - 1));
const cursor = parseJsonCursor<SharedLinkCursor>(pagination.after ?? null);
const cursorCondition = this.buildSharedLinkCursorCondition(
orderBy,
cursorView on GitHub (pinned to b4c8548c09)