{"record":{"id":"0b353bf2a9f62e99","repo":"supabase/supabase","slug":"error-message-0b353b","errorCode":null,"errorMessage":"error.message","messagePattern":"error\\.message","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"apps/studio/pages/api/platform/storage/[ref]/vector-buckets/[id]/indexes/index.ts","lineNumber":31,"sourceCode":"    case 'GET':\n      return handleGet(req, res)\n    case 'POST':\n      return handlePost(req, res)\n\n    default:\n      res.setHeader('Allow', ['GET', 'POST'])\n      res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } })\n  }\n}\n\nconst handleGet = async (req: NextApiRequest, res: NextApiResponse) => {\n  const { id } = req.query\n\n  const { data, error } = await supabase.storage.vectors\n    .from(id as string)\n    .listIndexes({ maxResults: 100 })\n\n  if (error) return res.status(500).json({ error: { message: error.message } })\n\n  const indexes = await Promise.all(\n    data.indexes.map(async ({ indexName }) => {\n      return (await supabase.storage.vectors.from(id as string).getIndex(indexName)).data?.index\n    })\n  )\n\n  return res.status(200).json({ indexes, nextToken: data.nextToken })\n}\n\nconst handlePost = async (req: NextApiRequest, res: NextApiResponse) => {\n  const { id } = req.query\n  const { indexName, dataType, dimension, distanceMetric, metadataKeys } = req.body\n  const payload = {\n    indexName,\n    dataType,\n    dimension,\n    distanceMetric,","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/pages/api/platform/storage/[ref]/vector-buckets/[id]/indexes/index.ts#L13-L49","documentation":"Passthrough of supabase-js storage.vectors.from(id).listIndexes() error as a 500. The route calls listIndexes({ maxResults: 100 }) and, on success, fans out to getIndex(indexName) for each result via Promise.all to enrich. Because the error is mapped to 500, even client-shaped causes (wrong bucket id, vectors disabled) look like server faults. The fan-out also means a single getIndex failure would throw an unhandled rejection rather than hit this branch.","triggerScenarios":"GET .../vector-buckets/[id]/indexes where the bucket does not exist, vectors are not enabled on storage-api, the admin key is wrong, or one of the inner getIndex calls rejects (which would crash the handler, not return this 500).","commonSituations":"Studio ahead of storage-api (no vectors support); bucket id typo; storage-api down; network blip during the fan-out enrichment causing a partial failure.","solutions":["Read the underlying error from server logs — the 500 message is the raw listIndexes error.","Confirm the bucket id exists and vectors are enabled on storage-api.","Guard the Promise.all fan-out: wrap each getIndex in allSettled so one failing index doesn't sink the whole list.","Verify SUPABASE_SERVICE_KEY/SUPABASE_URL and storage-api health."],"exampleFix":"// before\nconst indexes = await Promise.all(\n  data.indexes.map(async ({ indexName }) => {\n    return (await supabase.storage.vectors.from(id).getIndex(indexName)).data?.index\n  })\n)\n// after — tolerate partial failures\nconst results = await Promise.allSettled(\n  data.indexes.map(({ indexName }) =>\n    supabase.storage.vectors.from(id).getIndex(indexName).then((r) => r.data?.index)\n  )\n)\nconst indexes = results.filter((r) => r.status === 'fulfilled').map((r) => r.value)","handlingStrategy":"fallback","validationCode":"// server-side guard against the fan-out throwing\n// (no client-side prevention for a 500 here)","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(url, { method: 'GET' })\n  if (res.status === 500) throw new Error('Vector index listing failed; check storage-api and bucket id')\n} catch (e) { /* retry or surface */ }","preventionTips":["Replace Promise.all with Promise.allSettled in the route's fan-out so one bad index doesn't sink the list","Confirm vectors are enabled on storage-api before calling","Keep the bucket id validated","Add server-side logging of the raw listIndexes error"],"tags":["storage","nextjs-api","vector-buckets","indexes","passthrough","self-hosted","fan-out"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}