{"record":{"id":"2fb67e716a0bca60","repo":"calcom/cal.diy","slug":"method-not-allowed","errorCode":null,"errorMessage":"Method Not Allowed","messagePattern":"Method Not Allowed","errorType":"http","errorClass":"HttpCode","httpStatus":405,"severity":"warning","filePath":"packages/app-store/alby/api/webhook.ts","lineNumber":23,"sourceCode":"import { handlePaymentSuccess } from \"@calcom/app-store/_utils/payments/handlePaymentSuccess\";\nimport { distributedTracing } from \"@calcom/lib/tracing/factory\";\nimport { albyCredentialKeysSchema } from \"@calcom/app-store/alby/lib\";\nimport parseInvoice from \"@calcom/app-store/alby/lib/parseInvoice\";\nimport { IS_PRODUCTION } from \"@calcom/lib/constants\";\nimport { HttpError as HttpCode } from \"@calcom/lib/http-error\";\nimport { getServerErrorFromUnknown } from \"@calcom/lib/server/getServerErrorFromUnknown\";\nimport prisma from \"@calcom/prisma\";\n\nexport const config = {\n  api: {\n    bodyParser: false,\n  },\n};\n\nexport default async function handler(req: NextApiRequest, res: NextApiResponse) {\n  try {\n    if (req.method !== \"POST\") {\n      throw new HttpCode({ statusCode: 405, message: \"Method Not Allowed\" });\n    }\n\n    const bodyRaw = await getRawBody(req);\n    const headers = req.headers;\n    const bodyAsString = bodyRaw.toString();\n\n    const parseHeaders = webhookHeadersSchema.safeParse(headers);\n    if (!parseHeaders.success) {\n      console.error(parseHeaders.error);\n      throw new HttpCode({ statusCode: 400, message: \"Bad Request\" });\n    }\n\n    const { data: parsedHeaders } = parseHeaders;\n\n    const parse = eventSchema.safeParse(JSON.parse(bodyAsString));\n    if (!parse.success) {\n      console.error(parse.error);\n      throw new HttpCode({ statusCode: 400, message: \"Bad Request\" });","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/packages/app-store/alby/api/webhook.ts#L5-L41","documentation":"Thrown by the Alby webhook handler when the request method is anything other than POST. Alby/Svix deliver webhook events as POST, so GET/HEAD probes are rejected with HTTP 405.","triggerScenarios":"An uptime/healthcheck bot hitting /api/alby/webhook with GET; a misconfigured webhook source retrying with GET; a browser navigation or prefetch to the URL.","commonSituations":"Monitoring tools pinging the webhook URL; sharing the webhook endpoint with a GET-based status check; manual browser open of the URL.","solutions":["Send only POST to the webhook - Alby/Svix always uses POST.","Use a separate dedicated health endpoint for GET-based uptime checks.","Verify the Alby webhook configuration points to this exact URL and method."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (req.method !== 'POST') {\n  // return 405 from a GET health endpoint instead of the webhook\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Point uptime checks at a dedicated health endpoint, not the webhook.","Configure Alby/Svix to deliver via POST only.","Document the webhook as POST-only for ops teams."],"tags":["alby","webhook","http-method","svix"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}