{"record":{"id":"360257331dcb49aa","repo":"supabase/supabase","slug":"method-method-not-allowed-360257","errorCode":null,"errorMessage":"Method ${method} Not Allowed","messagePattern":"Method (.+?) Not Allowed","errorType":"http","errorClass":null,"httpStatus":405,"severity":"warning","filePath":"apps/studio/pages/api/platform/projects/[ref]/content/item/[id].ts","lineNumber":16,"sourceCode":"import { NextApiRequest, NextApiResponse } from 'next'\n\nimport { apiWrapper } from '@/lib/api/apiWrapper'\nimport { getSnippet } from '@/lib/api/snippets.utils'\n\nconst wrappedHandler = (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)\n\nasync function handler(req: NextApiRequest, res: NextApiResponse) {\n  const { method } = req\n\n  switch (method) {\n    case 'GET':\n      return handleGetAll(req, res)\n    default:\n      res.setHeader('Allow', ['GET'])\n      res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } })\n  }\n}\n\nconst handleGetAll = async (req: NextApiRequest, res: NextApiResponse) => {\n  try {\n    const snippet = await getSnippet(req.query.id as string)\n\n    return res.status(200).json(snippet)\n  } catch (error) {\n    if (error instanceof Error && error.message.includes('not found')) {\n      return res.status(404).json({ message: 'Content not found.' })\n    }\n    return res.status(500).json({ data: null, error: { message: 'Internal Server Error' } })\n  }\n}\n\nexport default wrappedHandler\n","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/pages/api/platform/projects/[ref]/content/item/[id].ts#L1-L34","documentation":"Single-snippet endpoint keyed by [id]. Implements GET only (loads the snippet with its SQL content via getSnippet). Allow header lists GET. Other verbs return 405. Mutations live on /content (PUT/DELETE), not here.","triggerScenarios":"PUT, POST, PATCH, or DELETE to /api/platform/projects/[ref]/content/item/[id].","commonSituations":"A client trying to delete a snippet via its item URL; or PUT-updating through the item route.","solutions":["Use GET on /content/item/[id] to load a snippet's full body.","Use PUT/DELETE on /content (collection) for mutations.","Treat the item route as read-only."],"exampleFix":"// before\nawait fetch(`${base}/content/item/${id}`, { method: 'DELETE' }) // 405\n// after\nawait fetch(`${base}/content?ids=${id}`, { method: 'DELETE' })","handlingStrategy":"validation","validationCode":"function assertGetOnly(method: string) {\n  if (method.toUpperCase() !== 'GET') throw new Error('content/item/[id] is GET-only')\n}","typeGuard":null,"tryCatchPattern":"if (res.status === 405) {\n  throw new Error('Mutate via /content (PUT/DELETE), not /content/item/[id].')\n}","preventionTips":["Treat the item route as read-only (load full body on demand).","Route all writes through the /content collection."],"tags":["http","api-routes","method-not-allowed","snippets"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}