Skip to content

fix: Vercel 404 on /api/v1/meta and /api/v1/packages — path normalisation, kernel boot resilience, broker-optional metadata - #933

Merged
hotlong merged 3 commits into
mainfrom
copilot/fix-vercel-deployment-404-errors
Mar 19, 2026
Merged

fix: Vercel 404 on /api/v1/meta and /api/v1/packages — path normalisation, kernel boot resilience, broker-optional metadata#933
hotlong merged 3 commits into
mainfrom
copilot/fix-vercel-deployment-404-errors

Conversation

CopilotAI commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Studio's Vercel deployment returns 404 for /api/v1/meta and /api/v1/packages. Three independent root causes: no error handling in the serverless catch-all (boot failures silently swallowed), no path normalisation (some runtimes strip /api/ prefix), and handleMetadata() unconditionally calling ensureBroker() which throws 500 in lightweight setups.

apps/studio/api/[...path].ts — catch-all handler

  • Wrap getApp() + inner.fetch() in try-catch; boot failures return structured 500 JSON instead of being swallowed
  • Normalise request path: prepend /api if the runtime stripped the function directory prefix

apps/studio/api/_kernel.ts — kernel cold-start

  • Shared boot promise prevents concurrent cold-start requests from racing duplicate initialisations
  • Validate broker shim after kernel.bootstrap() — reattach if lost
  • Seed-data failures are non-fatal (logged, not thrown)

packages/runtime/src/http-dispatcher.ts — broker-optional metadata

  • handleMetadata() uses this.kernel.broker ?? null instead of this.ensureBroker()
  • All broker.call() sites guarded with if (broker) — falls back to protocol service → ObjectQL registry → hardcoded defaults
  • Direct registry path for object lookups when broker is unavailable:
// Before: always throws if broker is nullconstbroker=this.ensureBroker();// After: graceful degradationconstbroker=this.kernel.broker??null;// ...if(broker){constdata=awaitbroker.call('metadata.objects',{ packageId }, ...);return{handled: true,response: this.success(data)};}// Fallback: use ObjectQL registry directlyconstqlService=awaitthis.getObjectQLService();if(qlService?.registry){constobjs=qlService.registry.getAllObjects(packageId);return{handled: true,response: this.success({type: 'object',items: objs})};}

Tests

  • 5 new Hono tests: Vercel outer→inner delegation for meta, packages, discovery, path normalisation, error propagation
  • 7 new runtime tests: broker-less metadata degradation across all path shapes (root types, object list, single object, published, save)
Original prompt

This section details on the original issue you should resolve

<issue_title>Vercel 部署依然404:/api/v1/meta 和 /api/v1/packages 路由未生效且 broker 未挂载</issue_title>
<issue_description>## 复现问题描述
在 Vercel 上部署 ObjectStack Studio 后,/api/v1/meta/api/v1/packages 路由依然返回 404,控制台持续报错,前端核心元数据与包列表接口不可用。

客观现象

  • 访问 https://play.objectstack.ai/api/v1/meta 与 /api/v1/packages 返回 404
  • 控制台日志 [Console] Starting in Server mode,尝试 fetch /api/v1/packages 与 /api/v1/meta
  • HTTP response 多次 404 (Not Found)
  • 页面无法加载核心功能

深度分析

  1. Hono 路由 catch-all 实际是注册了,但 Vercel path prefix 很可能导致路径未命中
    • Vercel 的 /api/[...path].ts 路由和内部 createHonoApp 的 prefix /api/v1 可能双重叠加,或者存在被截断。
    • 若请求传递路径为 /v1/meta,但 Hono 注册路径为 /api/v1/meta,则完全无法匹配,直接 404。
  2. dispatcher.dispatch() 已覆盖 meta/packages 路由,问题多半在于 serverless 环境路径偏移。
  3. broker shim 挂载虽有实现,但 cold start 时 kernel/app 启动失败未捕获,可能直接甩 500,或者 broker 为 null 抛异常。
  4. handleMetadata/handlePackages 方法直接 ensureBroker(),一旦 broker 未挂载或初始化失败,会抛 500。

结论

推荐修复与长期方案

  1. 在 serverless handler 层打印路径/日志,定位请求 path 是否被修正或被截断。
  2. 梳理 prefix 和 handler注册,防止内部 Hono prefix 与 Vercel catch-all 产生双重前缀或错配。
  3. kernel/app 的初始化需要更健壮,所有异常都应有日志、并降级到健康提示,不应静默挂死。
  4. broker shim 强制挂载与 broker 相关依赖初始化需全程校验,并应支持无 broker 降级兼容。
  5. 补充 Vercel/serverless 路由端到端 e2e 测试用例。

相关分析已在 #930 提供,可附引用。

cc @hotlong </issue_description>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

@vercel

vercelBot commented Mar 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
objectstack-playReadyReadyPreview, CommentMar 18, 2026 3:17pm
specReadyReadyPreview, CommentMar 18, 2026 3:17pm

Request Review

CopilotAIand others added 2 commits March 18, 2026 15:08
…lient metadata
- api/[...path].ts: Add try-catch + path normalisation for /api prefix
- api/_kernel.ts: Boot promise lock, broker reattach, non-fatal seed errors
- http-dispatcher.ts: handleMetadata() no longer requires broker upfront
- Add 12 new tests for Vercel delegation and broker-less metadata handling
- Update CHANGELOG.md
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix 404 errors for /api/v1/meta and /api/v1/packages routesfix: Vercel 404 on /api/v1/meta and /api/v1/packages — path normalisation, kernel boot resilience, broker-optional metadataMar 18, 2026
CopilotAI requested a review from hotlongMarch 18, 2026 15:12
@hotlong
hotlong marked this pull request as ready for review March 19, 2026 02:13
CopilotAI review requested due to automatic review settings March 19, 2026 02:13
@hotlong
hotlong merged commit d0c58d6 into mainMar 19, 2026
5 checks passed

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Studio’s Vercel serverless routing failures for /api/v1/meta and /api/v1/packages by hardening the serverless catch-all, making kernel boot more resilient under cold-start concurrency, and allowing metadata handling to degrade gracefully when a broker is unavailable.

Changes:

  • Add request path normalization + structured error handling in the Vercel catch-all handler.
  • Add a shared boot promise and non-fatal seeding behavior to prevent cold-start races and improve resiliency.
  • Make HttpDispatcher.handleMetadata() broker-optional with ObjectQL registry fallbacks; add tests for broker-less behavior and delegation behavior in the Hono adapter.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
apps/studio/api/[...path].tsWraps serverless delegation in try/catch and normalizes paths to preserve /api prefix before forwarding to the inner Hono app.
apps/studio/api/_kernel.tsAdds cold-start initialization lock via shared promise; validates broker shim; makes seeding non-fatal.
packages/runtime/src/http-dispatcher.tsUpdates metadata handler to avoid requiring a broker and to fall back to protocol/ObjectQL registry where possible.
packages/runtime/src/http-dispatcher.test.tsAdds tests validating metadata degradation behavior when the kernel has no broker.
packages/adapters/hono/src/hono.test.tsAdds tests for outer→inner Hono delegation and intended path normalization/error propagation scenarios.
CHANGELOG.mdDocuments the Vercel routing fix, kernel boot resiliency, and broker-optional metadata behavior.

}
// Try listing items of the given type
const items = qlService.registry.listItems?.(typeOrName, packageId);
if (items && items.length > 0) {
Comment on lines +604 to +613
it('handles path normalisation (strips prefix correctly) through delegation', async () => {
const innerApp = createHonoApp({ kernel: mockKernel, prefix: '/api/v1' });

const outerApp = new Hono();
outerApp.all('/*', async (c) => {
// Simulate the normalisation logic from [...path].ts
const url = new URL(c.req.url);
if (!url.pathname.startsWith('/api')) {
url.pathname = '/api' + url.pathname;
const request = new Request(url.toString(), c.req.raw);
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vercel 部署依然404:/api/v1/meta 和 /api/v1/packages 路由未生效且 broker 未挂载

3 participants

@hotlong