supabase/supabase · warning

Method ${method} Not Allowed

Error message

Method ${method} Not Allowed

What it means

HTTP 405 from the filter-v1 route when the request method is not POST. Same switch/default pattern as the other AI routes: only 'POST' is handled, everything else gets Allow: POST and this interpolated message.

Source

Thrown at apps/studio/pages/api/ai/sql/filter-v1.ts:24

import { DEFAULT_COMPLETION_MODEL } from '@/lib/ai/model.utils'
import { apiWrapper } from '@/lib/api/apiWrapper'
import {
  filterGroupSchemaForAI,
  requestSchema,
  serializeOperators,
  serializeOptions,
  validateFilterGroup,
} from '@/lib/api/filterHelpers'

async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { method } = req

  switch (method) {
    case 'POST':
      return handlePost(req, res)
    default:
      res.setHeader('Allow', ['POST'])
      res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } })
  }
}

export async function handlePost(req: NextApiRequest, res: NextApiResponse) {
  const parseResult = requestSchema.safeParse(req.body)

  if (!parseResult.success) {
    const errorMessage = parseResult.error.errors.map((e) => e.message).join(', ')
    return res.status(400).json({ error: errorMessage })
  }

  const { prompt, filterProperties } = parseResult.data

  try {
    const { modelParams, error: modelError } = await getModel({
      provider: 'openai',
      modelEntry: DEFAULT_COMPLETION_MODEL,
    })

View on GitHub (pinned to beee91b9c2)

Solutions

  1. Send method: 'POST' with a JSON body to /api/ai/sql/filter-v1.
  2. Use curl -X POST for manual testing.
  3. Confirm no trailing whitespace in the method string.

Example fix

// before
fetch('/api/ai/sql/filter-v1')
// after
fetch('/api/ai/sql/filter-v1', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ prompt: 'show active users', filterProperties: [...] }),
})
Defensive patterns

Strategy: validation

Validate before calling

const opts = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt, filterProperties }) }
if (opts.method !== 'POST') throw new Error('filter-v1 requires POST')

Type guard

function isPostInit(init?: RequestInit): init is RequestInit & { method: 'POST' } {
  return !!init && (init.method ?? 'GET') === 'POST'
}

Prevention

When it happens

Trigger: GET request to /api/ai/sql/filter-v1, an OPTIONS preflight, or a client using PUT/PATCH. Also any method string that doesn't strictly equal 'POST' (whitespace, casing).

Common situations: Browser navigation to the URL, curl without -X POST, a fetch wrapper defaulting to GET, or a proxy rewriting the verb.

Related errors


AI-assisted analysis of supabase/supabase@beee91b9c2 (2026-08-12). Data as JSON: /api/errors/ace5c8fce31304e1. Report an issue: GitHub.