BloopAI/vibe-kanban · error · Error
Invitation not found (${res.status})
Error message
Invitation not found (${res.status}) What it means
getInvitation looks up a pending invitation by its token at GET {API_BASE}/v1/invitations/{token}. The function throws this Error whenever the HTTP response is not ok (res.ok false), regardless of status code. It is a plain Error with only the status number embedded in the message, so callers cannot branch on the status programmatically.
Source
Thrown at packages/remote-web/src/shared/lib/api.ts:120
password: string,
): Promise<LocalLoginResponse> {
const res = await fetch(`${API_BASE}/v1/auth/local/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
if (!res.ok) {
throw new Error(`Local login failed (${res.status})`);
}
return res.json();
}
export async function getInvitation(
token: string,
): Promise<InvitationLookupResponse> {
const res = await fetch(`${API_BASE}/v1/invitations/${token}`);
if (!res.ok) {
throw new Error(`Invitation not found (${res.status})`);
}
return res.json();
}
export async function acceptInvitation(
token: string,
accessToken: string,
): Promise<AcceptInvitationResponse> {
const res = await fetch(`${API_BASE}/v1/invitations/${token}/accept`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
});
if (!res.ok) {
throw new Error(`Failed to accept invitation (${res.status})`);
}View on GitHub (pinned to 4deb7eca8f)
Solutions
- Ask the organization admin to resend a fresh invitation and open the new link.
- Verify the token in the URL matches the invitation exactly (no truncation/copy errors).
- Check VITE_API_BASE_URL points at the running remote server; a wrong base makes every lookup 404.
- Inspect res.status in the message: 404 = not found/already used, 410 = expired, 5xx = server-side issue to report.
Example fix
// before: single generic throw, status only in message
if (!res.ok) {
throw new Error(`Invitation not found (${res.status})`);
}
// after: attach status and clearer message per case
if (!res.ok) {
const err = new Error(
res.status === 404
? "Invitation not found, already used, or revoked"
: res.status === 410
? "This invitation has expired"
: `Invitation lookup failed (${res.status})`,
);
(err as Error & { status: number }).status = res.status;
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof token !== 'string' || token.trim() === '') {
throw new Error('Invitation token is missing or empty');
}
if (!import.meta.env.VITE_API_BASE_URL && import.meta.env.PROD) {
console.warn('VITE_API_BASE_URL is not set; requests go to same origin');
} Type guard
function isInvitationLookup(v: unknown): v is InvitationLookupResponse {
const r = v as InvitationLookupResponse;
return (
!!r && typeof r.id === 'string' && typeof r.organization_slug === 'string' &&
typeof r.role === 'string' && typeof r.expires_at === 'string'
);
} Try / catch
try {
const invitation = await getInvitation(token);
// render invitation details
} catch (e) {
const status = Number(/\((\d{3})\)$/.exec((e as Error).message)?.[1]);
if (status === 404) show('Invitation not found or already used');
else if (status === 410) show('This invitation has expired');
else show('Could not load the invitation. Please try the link again.');
} Prevention
- Validate the token is present and well-formed before calling the API.
- Render a friendly expired/used-invitation screen instead of a raw error.
- Warn users that invitation links are single-use and time-limited.
- Set VITE_API_BASE_URL explicitly per environment to avoid 404s from a wrong origin.
When it happens
Trigger: GET /v1/invitations/{token} returns 404 (token unknown, invitation already accepted or revoked), 410 (expired invitation per expires_at), or any 4xx/5xx from the remote server. Also fires when API_BASE (VITE_API_BASE_URL) is wrong and the request hits a route that doesn't exist.
Common situations: User opens an invitation link after the invite expired; user re-opens a link after already accepting the invite; someone mangles the token in the URL; the remote-web app points at the wrong backend URL so the route 404s.
Related errors
- Failed to accept invitation (${res.status})
- Failed to list organizations (${res.status})
- Failed to fetch identity (${res.status})
- Failed to list projects (${res.status})
- Host returned HTTP ${response.status}
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/ef01357ef96eb7fa.
Report an issue: GitHub.