Skip to content

Commit 04eb407

Browse files
author
CodeBuddy Attribution Bot
committed
fix(attribution): MCP uploadFiles 工具上传成功后静态托管仍返回 404,缺少部署完整性校验与后置步骤引导 (issue_moj0dwx7_bkz1io)
1 parent e2ca73f commit 04eb407

6 files changed

Lines changed: 31 additions & 6 deletions

File tree

config/source/guideline/cloudbase/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ Prefer long-term memory when available: write the scenarios and working rules th
290290
- Use CloudBase static hosting after build completion
291291
- Refer to the `web-development` skill for deployment process
292292
- `uploadFiles` is for static hosting only; if the task needs a COS object that must be queried or polled with the storage SDK, use `manageStorage` / `queryStorage`
293+
- **Subdirectory deployment pre-check (most common 404 cause):** Before calling `uploadFiles` for a subdirectory deploy, confirm: (1) `base`/`publicPath`/`assetPrefix` is set to the absolute subdirectory path with leading and trailing slashes (e.g. `/vite-test/`), NOT `'./'`; (2) project rebuilt after config change; (3) built files reference assets with the subdirectory prefix; (4) entire `dist/` uploaded, not just `index.html`
294+
- `cloudPath` for `uploadFiles` is relative to hosting root — no leading `/` (e.g. `vite-test`, not `/vite-test`)
293295
- Remind users that CDN has a few minutes of cache after deployment
294296

295297
**Backend Deployment:**

config/source/skills/cloudbase-platform/SKILL.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ Use this skill for **CloudBase platform knowledge** when you need to:
102102
- Cloud storage is suitable for files with privacy requirements, can get temporary access addresses via temporary file URLs
103103
- If the task needs COS SDK polling, file metadata lookup, or temporary URLs for an uploaded object, use cloud storage tools (`manageStorage` / `queryStorage`), not `uploadFiles`
104104

105+
2. **Static Hosting Subdirectory Deployment (most common 404 cause)**:
106+
- When deploying to a subdirectory (e.g. `/vite-test`), the build config `base`/`publicPath`/`assetPrefix` MUST be set to the absolute path matching the target with both leading and trailing slashes (e.g. `/vite-test/`)
107+
- **NEVER use `'./'` or empty string** for subdirectory deployments — relative paths break when the access URL lacks a trailing slash, causing all JS/CSS assets to 404
108+
- Before calling `uploadFiles` for a subdirectory deploy, confirm ALL of the following (any failure = deployment will break):
109+
1. Build config `base`/`publicPath`/`assetPrefix` is set to the absolute subdirectory path (e.g. `/vite-test/`)
110+
2. Project has been rebuilt after the config change
111+
3. Built files in `dist/` reference assets with the subdirectory absolute path, not root `/`
112+
4. The entire `dist/` directory is uploaded, not just `index.html`
113+
- `uploadFiles` `cloudPath` format: relative to hosting root, do NOT include a leading `/` (e.g. `vite-test`, not `/vite-test`)
114+
105115
2. **Static Hosting Domain**:
106116
- CloudBase static hosting domain can be obtained via `getWebsiteConfig` tool
107117
- Combine with static hosting file paths to construct final access addresses

config/source/skills/web-development/SKILL.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,14 @@ Use this section only when the Web project needs CloudBase platform features.
128128
### Static hosting defaults
129129

130130
- Build before deployment
131-
- Prefer relative asset paths for static hosting compatibility
131+
- **Subdirectory deployment is the most common source of 404 errors.** When deploying to a subdirectory (e.g. `/vite-test`), the build config `base`/`publicPath`/`assetPrefix` MUST be set to an absolute path matching the target subdirectory with both leading and trailing slashes (e.g. `/vite-test/`). **NEVER use `'./'` or empty string** for subdirectory deployments — when the access URL lacks a trailing slash, relative paths resolve incorrectly and all JS/CSS assets will 404.
132+
- Before calling `uploadFiles`, verify all of the following (any item failing means deployment will break):
133+
1. `base`/`publicPath`/`assetPrefix` is set to the absolute subdirectory path (e.g. `/vite-test/`)
134+
2. The project has been rebuilt after changing build config
135+
3. The built files in `dist/` reference assets with the subdirectory absolute path, not root `/`
136+
4. The entire `dist/` directory is uploaded, not just `index.html`
137+
- `cloudPath` for `uploadFiles` is relative to the hosting root — do NOT include a leading `/` (e.g. `vite-test`, not `/vite-test`)
132138
- Use hash routing by default when the project lacks server-side route rewrites
133-
- If the user does not specify a root path, avoid deploying directly to the site root by default
134139

135140
### CloudBase quick start
136141

config/source/skills/web-development/frameworks.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
- Treat Vite as the default choice for new Web app setup unless the repo already standardizes on another bundler.
1919
- Keep environment-specific values in `.env` or the project's existing config pattern instead of hardcoding them into UI files.
20+
- **Subdirectory deployment base config (most common Vite 404 cause):**
21+
- When deploying to a subdirectory like `/vite-test`, set `base: '/vite-test/'` in `vite.config.ts` — absolute path with leading AND trailing slash.
22+
- **NEVER use `base: './'` or `base: ''`** for subdirectory deployments. When the browser accesses `https://domain.com/vite-test` (no trailing slash), relative paths resolve to `/` instead of `/vite-test/`, causing all JS/CSS assets to 404.
23+
- After changing `base`, you MUST rebuild (`vite build`) before uploading — the built `dist/` files must reference assets with the subdirectory prefix.
24+
- When uploading with `uploadFiles`, set `cloudPath` to the subdirectory without a leading slash (e.g. `vite-test`, not `/vite-test`).
2025
- Check route base paths, asset paths, and build output behavior before deployment.
2126

2227
## Routing and build defaults

mcp/src/tools/hosting.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function buildUploadFilesErrorMessage(error: unknown, localPath?: string): strin
6060
suggestions.push(`请先确认本地路径 \`${localPath}\` 存在且当前进程有读取权限。`);
6161
}
6262
suggestions.push("如果报错的是构建产物中的某个静态资源文件,请检查构建后的资源引用路径是否正确。");
63-
suggestions.push("若站点部署到子路径,请确认 `publicPath`、`base`、`assetPrefix` 等配置没有把资源指向不存在的位置。");
63+
suggestions.push("若站点部署到子路径,请确认 `base`/`publicPath`/`assetPrefix` 已设为与部署路径一致的绝对路径(如 `/vite-test/`),禁止使用 `./` 等相对路径。");
6464
}
6565

6666
if (suggestions.length === 0) {
@@ -258,10 +258,10 @@ export function registerHostingTools(server: ExtendedMcpServer) {
258258
"uploadFiles",
259259
{
260260
title: "上传静态文件",
261-
description: "上传文件到静态网站托管,仅用于 Web 站点部署,不用于云存储对象上传。部署前请先完成构建;如果站点会部署到子路径,请检查构建配置中的 publicPath、base、assetPrefix 等是否使用相对路径,避免静态资源加载失败。若需要上传 COS 云存储文件,请使用 manageStorage。对于本地评测、现有脚手架补全或仅需本地开发服务器验证的任务,通常不需要调用此工具,除非用户明确要求部署站点。",
261+
description: "上传文件到静态网站托管,仅用于 Web 站点部署,不用于云存储对象上传。部署前请先完成构建。若需要上传 COS 云存储文件,请使用 manageStorage。对于本地评测、现有脚手架补全或仅需本地开发服务器验证的任务,通常不需要调用此工具,除非用户明确要求部署站点。\n\n⚠️ 子目录部署强制前置检查(部署到非根路径时必须逐项确认,任何一项未通过禁止调用此工具):\n1. 已在构建配置中设置 base/publicPath/assetPrefix,值必须与部署目标子目录一致(如部署到 /vite-test 则设为 '/vite-test/';必须使用绝对路径带前导和尾部斜杠,禁止使用 './' 等相对路径,因为访问 URL 不带尾部斜杠时会导致资源 404)\n2. 修改构建配置后已重新执行构建\n3. 已验证构建产物(dist/)中的资源引用路径已更新为子目录绝对路径(非 '/' 根路径)\n4. 上传整个构建产物目录(通常是 dist/),不能只上传 index.html\n\ncloudPath 格式:相对于托管根目录,不要带前导 '/',例如 'vite-test' 而非 '/vite-test'。",
262262
inputSchema: {
263263
localPath: z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt。"),
264-
cloudPath: z.string().optional().describe("静态托管云端文件或文件夹路径,例如 files/data.txt。若部署到子路径,请同时检查构建配置中的 publicPath、baseassetPrefix 等是否为相对路径。云存储对象路径请改用 manageStorage。"),
264+
cloudPath: z.string().optional().describe("静态托管云端路径,相对于托管根目录,不要带前导 '/',例如 'vite-test' 而非 '/vite-test'。若部署到子路径,请确保已将构建配置的 base/publicPath/assetPrefix 设为与部署路径一致的绝对路径(如 '/vite-test/'),禁止使用 './'。云存储对象路径请改用 manageStorage。"),
265265
files: z.array(z.object({
266266
localPath: z.string(),
267267
cloudPath: z.string()

mcp/src/tools/storage-hosting-guidance.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ describe("storage and hosting tool guidance", () => {
3535

3636
expect(tools.uploadFiles.meta.description).toContain("仅用于 Web 站点部署");
3737
expect(tools.uploadFiles.meta.description).toContain("manageStorage");
38-
expect(tools.uploadFiles.meta.description).toContain("通常不需要调用此工具");
38+
expect(tools.uploadFiles.meta.description).toContain("子目录部署强制前置检查");
39+
expect(tools.uploadFiles.meta.description).toContain("禁止使用 './'");
40+
expect(tools.uploadFiles.meta.description).toContain("不要带前导 '/'");
3941
expect(tools.uploadFiles.meta.inputSchema.cloudPath.description).toContain("云存储对象路径请改用 manageStorage");
42+
expect(tools.uploadFiles.meta.inputSchema.cloudPath.description).toContain("不要带前导 '/'");
4043
expect(tools.manageStorage.meta.description).toContain("仅用于 COS/Storage 对象");
4144
expect(tools.manageStorage.meta.description).toContain("不用于静态网站托管");
4245
});

0 commit comments

Comments
 (0)