{"record":{"id":"d5c87c155508706b","repo":"toeverything/AFFiNE","slug":"query-too-long-d5c87c","errorCode":"query_too_long","errorMessage":"Query is too long, max length is ${max}.","messagePattern":"Query is too long, max length is (.+?)\\.","errorType":"exception","errorClass":"QueryTooLong","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/models/workspace-analytics.ts","lineNumber":572,"sourceCode":"      generatedAt: now,\n    };\n  }\n\n  async adminPaginateAllSharedLinks(\n    options: AdminAllSharedLinksOptions\n  ): Promise<\n    OptionalTotalPaginated<AdminSharedLinkNode> & {\n      analyticsWindow: TimeWindowDto;\n    }\n  > {\n    const pagination: PaginationInput = {\n      ...options.pagination,\n      first: Math.min(Math.max(options.pagination.first ?? 10, 1), 100),\n      offset: Math.max(options.pagination.offset ?? 0, 0),\n    };\n    const keyword = options.keyword?.trim();\n    if (keyword && keyword.length > DOC_MEMBER_QUERY_MAX_LENGTH) {\n      throw new QueryTooLong({ max: DOC_MEMBER_QUERY_MAX_LENGTH });\n    }\n\n    const includeTotal = options.includeTotal ?? false;\n    const orderBy = options.orderBy ?? 'UpdatedAtDesc';\n    const analyticsWindowDays = clampInt(\n      options.analyticsWindowDays,\n      1,\n      90,\n      DEFAULT_ANALYTICS_WINDOW_DAYS\n    );\n    const now = new Date();\n    const currentDay = startOfUtcDay(now);\n    const analyticsFrom = addUtcDays(currentDay, -(analyticsWindowDays - 1));\n\n    const cursor = parseJsonCursor<SharedLinkCursor>(pagination.after ?? null);\n    const cursorCondition = this.buildSharedLinkCursorCondition(\n      orderBy,\n      cursor","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/models/workspace-analytics.ts#L554-L590","documentation":"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.","triggerScenarios":"Calling the admin shared-links listing with options.keyword whose trimmed length exceeds 255 characters.","commonSituations":"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.","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."],"exampleFix":"// before\nconst result = await analytics.adminListSharedLinks({ keyword: longDump }); // > 255 chars -> QueryTooLong\n\n// after\nconst keyword = longDump.trim().slice(0, 255);\nconst result = await analytics.adminListSharedLinks({ keyword });","handlingStrategy":"validation","validationCode":"const MAX = 255;\nconst keyword = rawKeyword.trim();\nif (keyword.length > MAX) {\n  throw new ValidationError(`Query is too long, max length is ${MAX}.`);\n}\nconst page = await analytics.adminListSharedLinks({ keyword });","typeGuard":null,"tryCatchPattern":"try { await analytics.adminListSharedLinks({ keyword }); } catch (e) { if (e instanceof QueryTooLong) trimAndRetry(); else throw e; }","preventionTips":["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."],"tags":["search","input-length","validation","admin"],"backgroundTag":"query-length-limit-exceeded","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}