{"record":{"id":"b537c4d26ca6fbfe","repo":"Budibase/budibase","slug":"body-message","errorCode":null,"errorMessage":"${body.message}","messagePattern":"\\$\\{body\\.message\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/server/src/api/controllers/ops.ts","lineNumber":22,"sourceCode":"export async function log(ctx: Ctx<LogOpsRequest, void>) {\n  const body = ctx.request.body\n  console.trace(body.message, body.data)\n  console.debug(body.message, body.data)\n  console.info(body.message, body.data)\n  console.warn(body.message, body.data)\n  console.error(body.message, body.data)\n  ctx.status = 204\n}\n\nexport async function alert(ctx: Ctx<ErrorOpsRequest, void>) {\n  const body = ctx.request.body\n  logging.logAlert(body.message, new Error(body.message))\n  ctx.status = 204\n}\n\nexport async function error(ctx: Ctx<ErrorOpsRequest, void>) {\n  const body = ctx.request.body\n  throw new Error(body.message)\n}\n","sourceCodeStart":4,"sourceCodeEnd":24,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ops.ts#L4-L24","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (typeof message !== \"string\" || message.length > 2000) {\n  throw new Error(\"message must be a non-empty string under 2000 chars\")\n}\nawait api.post(\"/api/ops/error\", { message, raw: String(err) })\n","typeGuard":"const isReportable = (m: unknown): m is string =>\n  typeof m === \"string\" && m.trim().length > 0 && m.length <= 2000\n","tryCatchPattern":"try {\n  await api.post(\"/api/ops/error\", { message: err.message })\n} catch (reportErr) {\n  // fall back to client-side logging; reporting endpoint failure should not mask original error\n  console.error(\"failed to report error\", reportErr)\n}\n","preventionTips":["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"],"tags":["ops","client-error","logging"],"backgroundTag":"client-error-reporting","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}