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
- Read the logged stack/context to find the original client-side error
- Reproduce the message in the browser console to identify the frontend bug
- Fix the underlying client error that generated the report
- 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
- Treat this endpoint as fire-and-forget telemetry, not an API to call directly
- Rate-limit or authenticate the ops endpoint in self-hosted deployments
- Sanitize messages client-side to avoid leaking sensitive data into server logs
- Set up log filtering to group noisy repeated client errors
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.