Skip to content

fix(vercel): force HTTPS for typescript-client git dep on Vercel#391

Merged
rbren merged 1 commit into
mainfrom
fix/vercel-typescript-client-https
May 12, 2026
Merged

fix(vercel): force HTTPS for typescript-client git dep on Vercel#391
rbren merged 1 commit into
mainfrom
fix/vercel-typescript-client-https

Conversation

@rbren
Copy link
Copy Markdown
Member

@rbren rbren commented May 12, 2026

What

Make Vercel builds resolve the @openhands/typescript-client git dep over HTTPS in a way that survives future npm install runs.

Why

Every recent Vercel preview build has been failing with:

[MISSING_EXPORT] ConversationClient is not exported by
node_modules/@openhands/typescript-client/dist/clients.js
...
Error: Command "npm run build" exited with 1

Root cause (also documented in #384):

  • npm normalizes the github:OpenHands/typescript-client#sha shorthand — and even an explicit git+https://github.com/... URL — to git+ssh://git@github.com/... whenever it rewrites package-lock.json during a plain npm install.
  • Vercel's build environment has no GitHub SSH key, so an ssh-pinned lockfile causes Vercel to fall back to a stale cached copy of the package whose dist/clients.js predates the addition of ConversationClient, FileClient, and SharedClient. Rolldown then fails the build with the missing-export errors above.
  • fix(frontend): use HTTPS instead of SSH for typescript-client git dep #382 fixed this once by hand-editing the lockfile, but the very next local npm install (e.g. feat: add LLM profiles API layer and React Query hooks #387 bumping the React Query hooks) silently rewrote the resolved URL back to ssh and the bug returned.

How

Make the Vercel build self-healing instead of relying on the lockfile staying clean forever:

  1. package.json now pins the dep as an explicit git+https://github.com/OpenHands/typescript-client.git#<sha> URL, so the intent is documented in one place rather than relying on the github: shorthand.
  2. package-lock.json's top-level dep spec is brought in line with that URL. The nested node_modules/@openhands/typescript-client entry already resolved to https, so this only changes the root-level packages."" spec.
  3. vercel.json sets installCommand to bash scripts/vercel-install.sh.
  4. scripts/vercel-install.sh (new):
    • rewrites any leftover git+ssh://git@github.com/ resolved URLs in package-lock.json back to git+https://github.com/ (handles future regressions where someone re-runs npm install locally and pushes an ssh-pinned lockfile);
    • configures git config --global url."https://github.com/".insteadOf for both ssh://git@github.com/ and git@github.com:, so anything npm has already cached internally as an ssh URL still resolves over https;
    • then runs npm ci for a strict, lockfile-driven install.
  5. AGENTS.md documents the protocol so future agents understand why the dep is pinned as git+https:// and what scripts/vercel-install.sh is for.

Verification

Locally on the failing main commit (78713e7):

  • bash scripts/vercel-install.sh produces a clean install with the https-resolved typescript-client and the full dist/clients.js that exports ConversationClient, FileClient, SharedClient, etc.
  • npm run build succeeds.
  • npm run lint succeeds (0 errors; pre-existing warnings unchanged).
  • Re-running npm install after the install rewrites resolved back to git+ssh as expected — but the next bash scripts/vercel-install.sh normalizes it again, so the lockfile drift no longer breaks Vercel deploys.

Notes

  • This only changes Vercel's install path; CI continues to run npm ci directly and is unaffected.
  • The fix does not require a @openhands/typescript-client npm publish or a new SHA; the existing ef62e82fc3dfb03991a1c8025429caf354427263 pin is correct and contains all required exports.

Refs: #384, #382


This PR was created by an AI agent (OpenHands) on behalf of @rbren.

npm normalizes the `github:OpenHands/typescript-client#sha` shorthand
(and even an explicit `git+https://github.com/...` URL) to
`git+ssh://git@github.com/...` whenever it rewrites package-lock.json
during a plain `npm install`. Vercel's build environment has no GitHub
SSH key, so an ssh-pinned lockfile causes Vercel to fall back to a stale
cached copy of the package whose dist/clients.js predates the addition
of ConversationClient, FileClient, and SharedClient. Rolldown then
fails the build with:

  [MISSING_EXPORT] ConversationClient is not exported by
  node_modules/@openhands/typescript-client/dist/clients.js

PR #382 fixed this once by hand-editing the lockfile, but the very next
local `npm install` (e.g. PR #387 bumping React Query hooks) silently
rewrote the resolved URL back to ssh and the bug returned.

This change makes the Vercel build self-healing:

* package.json now pins the dep as an explicit `git+https://` URL so
  the intent is documented in one place.
* package-lock.json's top-level dep spec matches that URL; the nested
  `node_modules/@openhands/typescript-client` entry already resolved
  to https, so this brings both halves of the lockfile in sync.
* vercel.json sets `installCommand` to `bash scripts/vercel-install.sh`,
  which:
    - rewrites any leftover `git+ssh://git@github.com/` resolved URLs
      back to https (handles future regressions),
    - configures `git config --global url."https://github.com/".insteadOf`
      for both `ssh://git@github.com/` and `git@github.com:` (handles
      anything npm has already normalized in cache),
    - then runs `npm ci` for a strict, lockfile-driven install.

Locally verified:

* `bash scripts/vercel-install.sh` produces a clean install with the
  https-resolved typescript-client.
* `npm run build` and `npm run lint` both succeed after the install.
* Re-running `npm install` rewrites `resolved` back to `git+ssh` as
  expected — the install script normalizes it again on every Vercel
  build, so the lockfile drift no longer breaks deploys.

Refs: #384 (Vercel preview build fails: MISSING_EXPORT for SharedClient
/ ConversationClient / FileClient).

Co-authored-by: openhands <openhands@all-hands.dev>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

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

Project Deployment Actions Updated (UTC)
agent-canvas Ready Ready Preview, Comment May 12, 2026 9:02pm

Request Review

Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

🟢 Good taste - Simple, defensive solution to a real production problem.

The two-pronged approach (lockfile rewrite + git config) makes this self-healing even if future local npm install runs re-introduce the ssh URL. Script is clean with proper error handling.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟢 LOW
    • Only affects Vercel's install path (CI and local dev unchanged)
    • Reversible (can remove vercel.json if needed)
    • Script runs in isolated Vercel build containers with no side effects
    • Manual verification documented in PR description

VERDICT:
Worth merging: Pragmatic fix for npm's URL normalization behavior that broke Vercel builds

KEY INSIGHT:
Making the build self-healing (via the install script) is better than relying on manual lockfile discipline. The git config --global in an ephemeral CI container is clever defensive programming.

@rbren rbren merged commit df8184f into main May 12, 2026
10 checks passed
@rbren rbren deleted the fix/vercel-typescript-client-https branch May 12, 2026 21:08
Sign up for free to 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.

3 participants