Budibase/budibase · warning · Error

${body.message}

Error message

${body.message}

What it means

The ops error endpoint (/api/ops/error) intentionally throws an Error built from the client-supplied body.message so that client-side errors are logged server-side via Koa error middleware (and surfaced to monitoring). The thrown message is fully attacker/user-controlled — it echoes whatever the client sent.

Source

Thrown at packages/server/src/api/controllers/ops.ts:22

export async function log(ctx: Ctx<LogOpsRequest, void>) {
  const body = ctx.request.body
  console.trace(body.message, body.data)
  console.debug(body.message, body.data)
  console.info(body.message, body.data)
  console.warn(body.message, body.data)
  console.error(body.message, body.data)
  ctx.status = 204
}

export async function alert(ctx: Ctx<ErrorOpsRequest, void>) {
  const body = ctx.request.body
  logging.logAlert(body.message, new Error(body.message))
  ctx.status = 204
}

export async function error(ctx: Ctx<ErrorOpsRequest, void>) {
  const body = ctx.request.body
  throw new Error(body.message)
}

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read the logged stack/context to find the original client-side error
  2. Reproduce the message in the browser console to identify the frontend bug
  3. Fix the underlying client error that generated the report
  4. If it's spam, restrict/rate-limit the ops endpoint and sanitize logged messages
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof message !== "string" || message.length > 2000) {
  throw new Error("message must be a non-empty string under 2000 chars")
}
await api.post("/api/ops/error", { message, raw: String(err) })

Type guard

const isReportable = (m: unknown): m is string =>
  typeof m === "string" && m.trim().length > 0 && m.length <= 2000

Try / catch

try {
  await api.post("/api/ops/error", { message: err.message })
} catch (reportErr) {
  // fall back to client-side logging; reporting endpoint failure should not mask original error
  console.error("failed to report error", reportErr)
}

Prevention

When it happens

Trigger: Any POST to the ops error endpoint with a body containing { message: "..." } — normally the frontend error reporter reporting uncaught client errors; also produced by misconfigured clients or anyone curling the endpoint.

Common situations: Builder/browser JS errors reported to the backend; noise in server logs from browser crashes; security scanners hitting the endpoint generating arbitrary log entries; log flooding/spam via crafted messages.

Related errors


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