toeverything/AFFiNE · error · NotFound
not_found
not_found
Error message
Invitation not found
What it means
Thrown by WorkspaceService invite-info lookup when inviteId is neither a cached link invitation ('workspace:inviteLinkId:<id>') nor an existing workspaceUser record — i.e. the invitation identifier does not exist anymore (or never did).
Solutions
- Ask the workspace owner to send a fresh invitation (link or email).
- Verify the inviteId matches the one embedded in the invite URL exactly.
- Self-hosted: confirm the cache (Redis) is running and was not flushed, since link invites live only in cache.
Defensive patterns
Strategy: try-catch
Try / catch
try {
const info = await gql.request(GET_INVITE_INFO, { inviteId });
} catch (e) {
if (getGraphqlErrorCode(e) === 'not_found') {
renderExpiredInvitePage(inviteId);
}
} Prevention
- Always resolve invite info before rendering an invite page; treat not_found as 'expired invitation'.
- Ask owners to generate fresh links rather than reusing old ones across long periods.
When it happens
Trigger: Calling the invite info query with an expired/already-consumed link invite id, an invitation record that was deleted (member removed), or a fabricated id.
Common situations: User opens an old invite page whose link invite expired in cache; the invited member was removed so the workspaceUser row is gone; self-hosted Redis flush wiped pending link invites.
Understand the failure class
Background: NOT_FOUND error code: why tRPC, Harbor, Nacos and other libraries return 404 "not found" errors for resources that may still exist — this error's family across 11 libraries.
Related errors
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/d1a4aba2326a2cf5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/service.ts:124
return storageUserIds;
}
async getInviteInfo(inviteId: string): Promise<InviteInfo> {
// invite link
const invite = await this.cache.get<InviteInfo>(
`workspace:inviteLinkId:${inviteId}`
);
if (typeof invite?.workspaceId === 'string') {
return {
...invite,
isLink: true,
};
}
const workspaceUser = await this.models.workspaceUser.getById(inviteId);
if (!workspaceUser) {
throw new NotFound('Invitation not found');
}
return {
isLink: false,
workspaceId: workspaceUser.workspaceId,
inviteeUserId: workspaceUser.userId,
inviterUserId: workspaceUser.inviterId,
};
}
async getWorkspaceInfo(workspaceId: string) {
const workspaceContent = await this.doc.getWorkspaceContent(workspaceId);
let avatar = DEFAULT_WORKSPACE_AVATAR;
if (workspaceContent?.avatarKey) {
try {
const owner = await this.models.workspaceUser.getOwner(workspaceId);
avatar = (View on GitHub (pinned to 2af30773ae)