Budibase/budibase · error

Recaptcha token not found

Error message

Recaptcha token not found

What it means

The recaptcha `verify` controller reads `token` from the request body and throws immediately if it is missing or falsy. The endpoint requires the client to supply the reCAPTCHA token obtained from the widget before server-side verification against Google can happen.

Source

Thrown at packages/server/src/api/controllers/recaptcha.ts:21

  VerifyRecaptchaRequest,
  VerifyRecaptchaResponse,
  CheckRecaptchaResponse,
  RecaptchaSessionCookie,
} from "@budibase/types"
import { utils, Cookie, configs, UnexpectedError } from "@budibase/backend-core"
import {
  setRecaptchaVerified,
  isRecaptchaVerified,
} from "../../utilities/redis"
import fetch from "node-fetch"

export async function verify(
  ctx: Ctx<VerifyRecaptchaRequest, VerifyRecaptchaResponse>
) {
  const { token } = ctx.request.body

  if (!token) {
    throw new Error("Recaptcha token not found")
  }

  const config = await configs.getRecaptchaConfig()
  if (!config) {
    throw new Error("No recaptcha config found")
  }

  try {
    const response = await fetch(
      "https://www.google.com/recaptcha/api/siteverify",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: new URLSearchParams({
          secret: config.config.secretKey,
          response: token,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Include the reCAPTCHA token in the request body under the `token` key: `{ token: grecaptcha.getResponse() }`
  2. Fix the client to render the reCAPTCHA widget and capture its token before submitting
  3. Check the field name matches `token` exactly
  4. Verify the widget actually executed (user completed the challenge) before sending

Example fix

// before
await api.post("/api/recaptcha/verify", { captcha: resp })
// after
const token = grecaptcha.getResponse()
if (!token) return
await api.post("/api/recaptcha/verify", { token })
Defensive patterns

Strategy: validation

Validate before calling

if (!body.token || typeof body.token !== "string") {
  throw new Error("Client must supply a recaptcha token before verifying")
}

Type guard

const hasRecaptchaToken = (b) =>
  typeof b === "object" && b !== null && "token" in b && typeof b.token === "string" && b.token.length > 0

Try / catch

try {
  await verifyRecaptcha({ token })
} catch (e) {
  if (String(e.message).includes("Recaptcha token not found")) {
    // re-render widget / ask user to complete the challenge
  }
}

Prevention

When it happens

Trigger: POSTing to the recaptcha verify endpoint with an empty body, `token: undefined/null/""`, or a request where the client-side widget never produced a token (script blocked, widget not rendered).

Common situations: Frontend forgot to call `grecaptcha.getResponse()`; ad blockers or CSP blocking the reCAPTCHA script so no token is generated; form field name mismatch (sending `captcha` or `recaptchaResponse` instead of `token`); API consumers calling the endpoint manually without the field.

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


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/0cf5645bb5305cfe. Report an issue: GitHub.