Skip to content

Fix RemoteTransport HttpClient2 constructor error in Vercel deployment#1113

Closed
Claude wants to merge 8 commits intomainfrom
claude/fix-find-operation-error
Closed

Fix RemoteTransport HttpClient2 constructor error in Vercel deployment#1113
Claude wants to merge 8 commits intomainfrom
claude/fix-find-operation-error

Conversation

@Claude
Copy link
Copy Markdown
Contributor

@Claude Claude AI commented Apr 13, 2026

The sys_metadata find operation was failing in production with RemoteTransport: lazy connect failed: HttpClient2 is not a constructor. This occurred when TursoDriver's lazy connection factory attempted to dynamically import @libsql/client.

Root cause: esbuild was bundling @libsql/client, which mangled internal class exports like HttpClient2, breaking the constructor at runtime.

Changes:

  • bundle-api.mjs: Mark @libsql/client as external to prevent bundling
  • vercel.json: Add @libsql/client to includeFiles pattern for serverless function packaging
  • build-vercel.sh: Copy @libsql/client from monorepo root to local node_modules during build

This follows the same deployment pattern as other external dependencies like better-sqlite3.

Claude AI and others added 2 commits April 13, 2026 02:12
- Mark @libsql/client as external in bundle-api.mjs
- Add @libsql/client to vercel.json includeFiles
- Prevents esbuild from bundling @libsql/client which breaks HttpClient2 constructor

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/bba47546-4868-4fbb-94cc-909dd5f6757d

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Update build-vercel.sh to copy @libsql/client to local node_modules
- Remove outdated comment about @libsql/client being bundled
- Ensures @libsql/client is available in Vercel serverless function

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/bba47546-4868-4fbb-94cc-909dd5f6757d

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 13, 2026

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

Project Deployment Actions Updated (UTC)
objectstack-play Error Error Apr 13, 2026 8:56am
spec Ready Ready Preview, Comment Apr 13, 2026 8:56am

Request Review

@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Apr 13, 2026

@claude[agent]
2026-04-13 01:34:52.440 [info] [Vercel] GET https://play.objectstack.ai/api/v1/meta/agent?path=v1%2Fmeta%2Fagent
2026-04-13 01:34:52.441 [info] {"timestamp":"2026-04-13T01:34:52.441Z","level":"debug","message":"Find operation starting","object":"sys_metadata","query":{"where":{"type":"agent","state":"active"}}}
2026-04-13 01:34:52.441 [info] {"timestamp":"2026-04-13T01:34:52.441Z","level":"debug","message":"No hooks registered for event","event":"beforeFind"}
2026-04-13 01:34:52.441 [error] {"timestamp":"2026-04-13T01:34:52.441Z","level":"error","message":"Find operation failed","object":"sys_metadata","error":{"message":"RemoteTransport: lazy connect failed: HttpClient2 is not a constructor","stack":"Error: RemoteTransport: lazy connect failed: HttpClient2 is not a constructor\n at file:///var/task/apps/studio/api/_handler.js:116328:17\n at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n at async RemoteTransport.find (file:///var/task/apps/studio/api/_handler.js:116027:5)\n at async file:///var/task/apps/studio/api/_handler.js:113836:22\n at async next (file:///var/task/apps/studio/api/_handler.js:113378:22)\n at async next (file:///var/task/apps/studio/api/_handler.js:113376:9)\n at async Object.fn (file:///var/task/apps/studio/api/_handler.js:142856:11)\n at async next (file:///var/task/apps/studio/api/_handler.js:113376:9)\n at async next (file:///var/task/apps/studio/api/_handler.js:113376:9)\n at async _ObjectQL2.executeWithMiddleware (file:///var/task/apps/studio/api/_handler.js:113381:5)"}}

@hotlong
Copy link
Copy Markdown
Contributor

hotlong commented Apr 13, 2026

@claude[agent] 2026-04-13 07:19:15.144 [info] [Vercel] GET https://objectstack-play-git-claude-fix-find-operat-bf9cc6-object-stack.vercel.app/api/v1/meta/tool?path=v1%2Fmeta%2Ftool
2026-04-13 07:19:15.144 [info] {"timestamp":"2026-04-13T07:19:15.139Z","level":"debug","message":"Find operation starting","object":"sys_metadata","query":{"where":{"type":"tool","state":"active"}}}
2026-04-13 07:19:15.144 [info] {"timestamp":"2026-04-13T07:19:15.139Z","level":"debug","message":"No hooks registered for event","event":"beforeFind"}
2026-04-13 07:19:15.144 [error] {"timestamp":"2026-04-13T07:19:15.140Z","level":"error","message":"Find operation failed","object":"sys_metadata","error":{"message":"RemoteTransport: lazy connect failed: Cannot find package '@libsql/client' imported from /var/task/apps/studio/api/_handler.js","stack":"Error: RemoteTransport: lazy connect failed: Cannot find package '@libsql/client' imported from /var/task/apps/studio/api/_handler.js\n at file:///var/task/apps/studio/api/_handler.js:103152:17\n at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n at async RemoteTransport.find (file:///var/task/apps/studio/api/_handler.js:102851:5)\n at async file:///var/task/apps/studio/api/_handler.js:100660:22\n at async next (file:///var/task/apps/studio/api/_handler.js:100202:22)\n at async next (file:///var/task/apps/studio/api/_handler.js:100200:9)\n at async Object.fn (file:///var/task/apps/studio/api/_handler.js:129680:11)\n at async next (file:///var/task/apps/studio/api/_handler.js:100200:9)\n at async next (file:///var/task/apps/studio/api/_handler.js:100200:9)\n at async _ObjectQL2.executeWithMiddleware (file:///var/task/apps/studio/api/_handler.js:100205:5)"}}

@Claude Claude AI requested a review from hotlong April 13, 2026 07:24
Copilot stopped work on behalf of hotlong due to an error April 13, 2026 07:24
Copilot stopped work on behalf of hotlong due to an error April 13, 2026 07:28
@xuyushun441-sys
Copy link
Copy Markdown
Contributor

@claude[agent] 继续

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/553ba115-2f78-433a-96c4-a8088eb6ebe3

Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
@Claude
Copy link
Copy Markdown
Contributor Author

Claude AI commented Apr 13, 2026

@claude[agent] 继续

Fixed in commit 044ae75. Added @libsql/client and better-sqlite3 as direct dependencies to apps/studio/package.json. This ensures the packages are installed in the local node_modules during Vercel deployment, allowing the dynamic import in TursoDriver's lazy connection factory to resolve correctly.

The previous approach of copying from the monorepo root didn't work because pnpm's strict node_modules structure doesn't hoist scoped packages. With these packages now as direct dependencies of the studio app, Vercel will include them in the serverless function deployment.

@xuyushun441-sys
Copy link
Copy Markdown
Contributor

@claude[agent] 继续

- Add @libsql/client and better-sqlite3 to lockfile
- Fixes CI "frozen-lockfile" error after adding dependencies to apps/studio/package.json

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/01213e25-6e79-4f4e-b29e-c08da6842337

Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
@Claude
Copy link
Copy Markdown
Contributor Author

Claude AI commented Apr 13, 2026

@claude[agent] 继续

Updated pnpm-lock.yaml in commit df3efb4. The CI was failing because the lockfile was out of sync after adding @libsql/client and better-sqlite3 dependencies to apps/studio/package.json. The lockfile has been regenerated and the CI should now pass.

@xuyushun441-sys
Copy link
Copy Markdown
Contributor

@claude[agent]
[bundle-api] Bundled server/index.ts → api/_handler.js
[build-vercel] Copying external native modules to local node_modules...
cp: cannot create regular file 'node_modules/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/n
cp: cannot create regular file 'node_modules/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/better-sqlite3/s

- Remove better-sqlite3 and @libsql/client from copy loop
- These are now direct dependencies installed by pnpm automatically
- Prevents infinite recursion error during Vercel build
- Keep only @ai-sdk copying logic for workspace dependencies

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/d15f5cb9-a33c-458c-aca4-417104e23d66

Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
@Claude
Copy link
Copy Markdown
Contributor Author

Claude AI commented Apr 13, 2026

@claude[agent]
[bundle-api] Bundled server/index.ts → api/_handler.js
[build-vercel] Copying external native modules to local node_modules...
...

Fixed in commit 466e085. The infinite recursion occurred because better-sqlite3 and @libsql/client are now direct dependencies in apps/studio/package.json (added in 044ae75), so pnpm installs them automatically into apps/studio/node_modules/. The build script was trying to copy these packages from the monorepo root to a location that already existed, causing the recursive loop.

Removed the redundant copy logic for these two packages since they're now installed directly by pnpm. Only @ai-sdk packages still need to be copied since they remain workspace dependencies.

@xuyushun441-sys
Copy link
Copy Markdown
Contributor

@claude[agent] The framework produced an invalid deployment package for a Serverless Function. Typically this means that the framework produces files in symlinked directories. Please verify the framework settings.

- Replace symlinked packages with real files in node_modules
- Vercel doesn't support symlinked directories in serverless functions
- Use readlink to get real path, then copy with cp -rL
- Prevents "invalid deployment package" error from Vercel
- Applies to better-sqlite3, @libsql/client, and @ai-sdk packages

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/131c9b60-a3c7-43b6-a080-0de180a91db0

Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
@Claude
Copy link
Copy Markdown
Contributor Author

Claude AI commented Apr 13, 2026

@claude[agent] The framework produced an invalid deployment package for a Serverless Function. Typically this means that the framework produces files in symlinked directories. Please verify the framew...

Fixed in commit e5d5c8d. Vercel rejects symlinked directories in serverless function packages. pnpm creates symlinks in node_modules by default, which caused the "invalid deployment package" error.

The build script now dereferences these symlinks by:

  1. Using readlink -f to get the real path the symlink points to
  2. Removing the symlink
  3. Copying the actual files with cp -rL to replace the symlink

This ensures @libsql/client, better-sqlite3, and @ai-sdk packages are real files that Vercel can package correctly.

@xuyushun441-sys
Copy link
Copy Markdown
Contributor

@claude[agent] [build-vercel] Done. Static files in public/, serverless function in api/[[...route]].js → api/_handler.js
Detected pnpm-lock.yaml version 9 generated by pnpm@10.x with package.json#packageManager pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268
Installing dependencies...
Scope: all 47 workspace projects
dependencies:

  • @libsql/client 0.17.2
  • better-sqlite3 12.9.0
    ../docs postinstall$ fumadocs-mdx
    ../docs postinstall: [MDX] generated files in 27.031339000000003ms
    ../docs postinstall: Done
    Done in 2.3s using pnpm v10.31.0
    Build Completed in /vercel/output [1m]
    Deploying outputs...
    The framework produced an invalid deployment package for a Serverless Function. Typically this means that the framework produces files in symlinked directories. Please verify the framework settings.

- Add .npmrc with node-linker=hoisted to apps/studio
- Prevents pnpm from creating symlinks in node_modules
- Vercel requires real files, not symlinks, in serverless functions
- Simplify build-vercel.sh by removing symlink dereferencing logic
- @libsql/client and better-sqlite3 will be installed as real directories

Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/500e4ff3-8d32-4122-bb49-7ab36dbba0d8

Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
@Claude
Copy link
Copy Markdown
Contributor Author

Claude AI commented Apr 13, 2026

@claude[agent] [build-vercel] Done. Static files in public/, serverless function in api/[[...route]].js → api/_handler.js
Detected pnpm-lock.yaml version 9 generated by pnpm@10.x with package.jso...

Fixed in commit 1fa5437. The symlink dereferencing approach wasn't sufficient because pnpm creates a complex symlink structure throughout node_modules.

The proper solution is to configure pnpm to use node-linker=hoisted in apps/studio/.npmrc. This tells pnpm to create a flat, traditional node_modules structure with real directories instead of symlinks. Vercel can now package the serverless function correctly without encountering any symlinked directories.

This is the standard approach for Vercel deployments with pnpm monorepos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants