You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase StorageApiError:资源未找到问题排查求助

问题:SvelteKit端点下载Supabase存储PDF文件失败(400错误)

尝试从SvelteKit端点下载Supabase存储桶中的PDF文件,已确认文件路径和桶名与实际存储桶一致,访问策略配置为“用户仅能访问自己的文件夹”,但调用官方下载方法后返回400错误,提示资源未找到,无法定位问题。

代码实现

import { supabase } from "$lib/js/supabaseClient.js";

async function downloadFile(bucketName, filePath) {
  try {
    const { data, error } = await supabase.storage.from(bucketName).download(filePath);

    if (error) {
      throw error;
    }

    console.log('File downloaded successfully:', data);
    return data;
  } catch (error) {
    console.error('Error downloading file:', error);
    return null;
  }
}

const downloaded_file = await downloadFile("PDF_files", filePath);

错误信息

Error downloading file: StorageApiError: The resource was not found
    at /Users/<user>/Library/Mobile Documents/com~apple~CloudDocs/Code/Svelte/<app>/node_modules/.pnpm/@supabase+storage-js@2.5.0/node_modules/@supabase/storage-js/dist/main/lib/fetch.js:22:20
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  __isStorageError: true,
  status: 400
}

Supabase日志详情

Log ID
793bc143-a6ab-47e3-bb48-bff6d88670ed

Log Timestamp (UTC)
2023-04-14T06:37:55.959Z

Log Event Message
GET | 400 | 10.105.42.177 | 7b79f167b38d0b44-AMS | /object/info/PDF_files/e2ab35ee-a24d-4956-8883-43b0c9aa9d1e/3c8229e1-2717-4b07-9add-000d04f39797.pdf | undefined

Log Metadata
[
  {
    "context": [
      {
        "host": <redacted>, 
        "pid": 1
      }
    ],
    "err": [],
    "error": [
      {
        "message": null,
        "postgresError": [
          {
            "code": "PGRST116",
            "details": "Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row",
            "hint": null,
            "message": "JSON object requested, multiple (or no) rows returned"
          }
        ],
        "errno": null,
        "config": [],
        "address": null,
        "status": 406,
        "command": [],
        "body": null,
        "routine": null,
        "expiredAt": null,
        "detail": null,
        "host": null,
        "code": null,
        "syscall": null,
        "validationContext": null,
        "__fault": null,
        "cause": [],
        "__metadata": [],
        "port": null,
        "stack": null,
        "validation": [],
        "hostname": null,
        "severity": null,
        "line": null,
        "httpStatusCode": null,
        "file": null,
        "status_code": null,
        "length": null,
        "metadata": [
          {
            "bucketId": "PDF_files",
            "name": "e2ab35ee-a24d-4956-8883-43b0c9aa9d1e/3c8229e1-2717-4b07-9add-000d04f39797.pdf",
            "names": []
          }
        ],
        "originalError": [],
        "statusCode": null,
        "name": null,
        "error": null
      }
    ],
    "job": [],
    "level": "info",
    "project": "fuphgoftssjnstwjtecp",
    "rawError": null,
    "req": [
      {
        "headers": [
          {
            "accept": null,
            "cf_cache_status": null,
            "cf_connecting_ip": "2a06:98c0:3600::103",
            "cf_ipcountry": null,
            "cf_ray": "7b79f167b38d0b44-AMS",
            "content_length": null,
            "content_location": null,
            "content_range": null,
            "content_type": null,
            "date": null,
            "host": "storage-api-lb-eu-central-1-ext.storage.supabase.com",
            "referer": null,
            "transfer_encoding": null,
            "user_agent": null,
            "x_client_info": null,
            "x_client_trace_id": null,
            "x_forwarded_proto": "https",
            "x_real_ip": null
          }
        ],
        "hostname": "storage-api-lb-eu-central-1-ext.storage.supabase.com",
        "method": "GET",
        "remoteAddress": "10.105.42.177",
        "remotePort": 38672,
        "url": "/object/info/PDF_files/e2ab35ee-a24d-4956-8883-43b0c9aa9d1e/3c8229e1-2717-4b07-9add-000d04f39797.pdf"
      }
    ],
    "reqId": "7b79f167b38d0b44-AMS",
    "res": [
      {
        "statusCode": 400
      }
    ],
    "responseTime": 106.6362340003252,
    "results": [],
    "tenantId": "fuphgoftssjnstwjtecp"
  }
]

存储桶访问策略配置

SELECT
Give users access to own folder 3ckb0q_0
INSERT
Give users access to own folder 3ckb0q_1
UPDATE
Give users access to own folder 3ckb0q_2
DELETE
Give users access to own folder 3ckb0q_3

4 policies in PDF_files

排查分析与解决办法

核心问题定位

从日志中的postgresError(代码PGRST116)可以看出,请求返回0行数据,说明Supabase要么找不到对应文件,要么权限策略拦截了查询,导致没有返回结果。结合你的场景,优先排查权限策略和用户认证问题。

具体解决步骤

  1. 确认Supabase客户端的认证状态
    SvelteKit端点中如果是服务器端路由,必须确保使用带用户会话的Supabase实例。如果直接导入未认证的客户端,会导致权限策略无法识别当前用户,拦截请求。推荐使用Supabase Auth Helpers创建服务器端客户端:

    import { createSupabaseServerClient } from '@supabase/auth-helpers-sveltekit';
    import { env } from '$env/dynamic/private';
    
    export async function GET({ request, cookies }) {
      const supabase = createSupabaseServerClient({
        supabaseUrl: env.SUPABASE_URL,
        supabaseKey: env.SUPABASE_SERVICE_ROLE_KEY,
        request,
        cookies
      });
      // 在此处调用downloadFile方法
    }
    
  2. 验证权限策略的逻辑正确性
    查看你创建的SELECT策略的具体SQL,确保它能正确匹配用户与文件夹:
    正确的策略SQL应该类似:

    CREATE POLICY "Give users access to own folder" ON storage.objects
    FOR SELECT USING (
      bucket_id = 'PDF_files' AND
      auth.uid() = split_part(name, '/', 1)
    );
    

    验证文件路径的第一部分(比如e2ab35ee-a24d-4956-8883-43b0c9aa9d1e)是否等于当前认证用户的UID,若不匹配,策略会拦截查询。

  3. 检查文件路径的大小写一致性
    Supabase存储的文件路径区分大小写,确认代码中的filePath与存储桶中的实际路径完全一致(包括大小写、斜杠方向)。

  4. 临时测试权限策略
    可以临时将SELECT策略改为允许所有访问(USING (true)),如果此时能成功下载文件,说明问题出在原策略逻辑上,再逐步调整回原策略并验证匹配条件。


内容的提问来源于stack exchange,提问作者Koen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:15:05