Budibase/budibase · error · HTTPError
token is required
Error message
token is required
What it means
resolveToken is a small helper that guarantees a link token exists before any chat identity link flow proceeds. Identity linking works by handing a one-time token from a chat channel to the web app via URL; without a token there is nothing to resolve. The throw is an HTTP 400 guarding routes like /api/chat-links/:instance/:token/... .
Source
Thrown at packages/server/src/api/controllers/ai/chatIdentityLinks.ts:112
outline: 2px solid #2680eb;
outline-offset: 2px;
}
@media (max-width: 480px) {
body {
padding: 24px;
}
main {
min-height: 360px;
}
h1 {
font-size: 22px;
}
}
`
const resolveToken = (token?: string) => {
if (!token) {
throw new HTTPError("token is required", 400)
}
return token
}
const assertSessionMatchesInstance = ({
workspaceId,
instance,
}: {
workspaceId?: string
instance: string
}) => {
if (!workspaceId || workspaceId !== instance) {
throw new HTTPError("Link token is not valid for this workspace", 400)
}
}
const getCurrentGlobalUserId = (ctx: UserCtx) => {
const currentUserId =View on GitHub (pinned to a81a902e9a)
Solutions
- Use the exact handoff/confirmation URL supplied by the chat channel message, including the token segment
- Regenerate the link token by re-issuing the link request from the chat (e.g. typing the link command again)
- Fix link-rendering code so the token is interpolated into the URL template
- Check route definitions so the :token param is actually captured by the router
Example fix
// before
const res = await fetch(`/api/chat-links/${instance}/handoff`)
// after
const res = await fetch(`/api/chat-links/${instance}/${token}/handoff`) Defensive patterns
Strategy: validation
Validate before calling
if (!token) throw new Error("chat link token missing from URL")
await fetch(`/api/chat-links/${instance}/${token}/handoff`) Type guard
function hasToken(params: { token?: string }): params is { token: string } {
return typeof params.token === "string" && params.token.length > 0
} Try / catch
try {
await api.handoffLink(instance, token)
} catch (e) {
if (e instanceof HTTPError && e.status === 400 && e.message === "token is required") {
// fix link construction / prompt user to use the full link
}
throw e
} Prevention
- Generate link URLs from a single template that interpolates the token
- Never truncate or manually retype link tokens
- Validate that the router captures the :token param
- E2E-test the full handoff URL produced by the chat message
When it happens
Trigger: Hitting a chat-links route (handoff or confirm) with an empty or missing :token path parameter, or calling resolveToken with undefined because the URL was constructed without the token segment.
Common situations: Manually typing/truncating the confirmation URL from an email/chat message; a chat bot rendering the link without the token placeholder substituted; links copied without the final path segment; redirect logic losing the token query/path param.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
- Invalid ${queryName} query
- Invalid environment query
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/f919ca7ef3504ca5.
Report an issue: GitHub.