-
Notifications
You must be signed in to change notification settings - Fork 79
Description
Describe the bug
When using the gel HTTP client (via createHttpClient) with a branch/database name that contains a / (for example preview/pr-662 or dev/riley), all queries fail with:
ProtocolError: fetch failed with status code 404: Not Found
The same branch works correctly with the gel CLI and other binary-protocol clients. The failure is specific to the HTTP client.
From debugging:
- The HTTP client constructs URLs for queries using the provided
branch/databasevalue directly in the path, e.g./db/${database}/…, without URL-encoding. - If
database === "preview/pr-662", the resulting path becomes/db/preview/pr-662/..., which the server interprets as multiple path segments instead of a single database/branch identifier. - The Gel API then cannot match the database/branch and returns
404, which the JS client surfaces as aProtocolError. - Changing only the branch name to one without
/(e.g.preview-pr-662) makes the HTTP client work again with no other changes.
This effectively means the HTTP client does not support otherwise-valid branch names containing /, while the CLI does.
Reproduction
Minimal reproduction based on the behavior seen in a production app:
-
In Gel (Cloud or self-hosted), create a branch whose name includes a
/:gel branch switch -c dev/test-slash --from main --copy-data
(Any valid name containing
/will do; in our real case we usedpreview/pr-662.) -
In an environment that uses the HTTP driver (Node with
fetch, Cloudflare Workers, etc.), connect withcreateHttpClient:import { createHttpClient } from 'gel'; const client = createHttpClient({ instanceName: process.env.GEL_INSTANCE!, // valid instance secretKey: process.env.GEL_SECRET_KEY!, // valid secret branch: 'dev/test-slash', // branch name with '/' }); await client.querySingle('SELECT 1');
-
Observe the behavior:
- The request results in
ProtocolError: fetch failed with status code 404: Not Found. - If you inspect the outgoing HTTP request, the URL path includes the branch name verbatim, e.g.
/db/dev/test-slash/..., splitting on/.
- The request results in
-
Now change only the branch name to a value without
/:const client = createHttpClient({ instanceName: process.env.GEL_INSTANCE!, secretKey: process.env.GEL_SECRET_KEY!, branch: 'dev-test-slash', // no slash });
- The same query now succeeds.
-
Using the
gelCLI against the/-containing branch (e.g.gel branch switch dev/test-slashand running queries) works as expected, confirming that:- The branch exists.
- The issue is isolated to how the JS HTTP client constructs its URLs.
Expected behavior
- Branch/database names that are valid in Gel (including names containing
/, such asdev/<user>orpreview/pr-<number>) should work with the HTTP client in exactly the same way they work with the CLI and binary clients. - The HTTP client should treat the branch/database identifier as data, not as raw path syntax. Concretely:
- When building URLs like
/db/${database}/…, it should percent-encodedatabase(and any similar identifiers) withencodeURIComponentor equivalent. - With proper encoding, a branch name like
preview/pr-662would be sent as/db/preview%2Fpr-662/..., allowing the server to resolve it correctly.
- When building URLs like
Versions (please complete the following information):
- OS:
- Reproduced in development on macOS (Apple Silicon).
- Reproduced in CI/preview on Linux (
ubuntu-latest) and Cloudflare Workers.
- Gel server:
- Managed Gel Cloud instance with branching enabled (preview/dev branches).
- Gel CLI:
gel2.x (CLI successfully works with/-containing branch names).
gelJS client:gelnpm package2.1.1(via an app-local wrapper aroundcreateHttpClient/createClient).
- Node:
- Node.js 22.x in application/CI.
- Deno:
- Not used.
- Runtime environments:
- Cloudflare Workers (with
nodejs_compat, usingcreateHttpClient). - Node.js with global
fetchavailable.
- Cloudflare Workers (with