#11753·cube

Cube Cloud API reports an unusable REST URL for branch staging environments (/dev-mode/ + URL-encoded branch → 400 "Bad branch")

Author: klekyCreated Sep 3, 2026Updated Sep 4, 2026

Summary

For a branch staging environment, GET /api/v1/deployments/{id}/environments returns a REST api_credentials.url that the deployment rejects with 400 BadRequestError: Bad branch.

The URL that actually works is the one shown in the Cube Cloud UI. Two things differ:

Path segment Branch in path
API returns /dev-mode/ URL-encoded (team%2Fmy-branch)
Works (and is what the UI shows) /staging/ raw (team/my-branch)

This surfaces through cube environments list <id> --json, but it is not a CLI rendering bug — the raw API response contains the same value (see below), so the CLI is faithfully passing through what the API returns.

Reproduction

  1. Register a branch whose name contains a / (e.g. team/my-branch) on a deployment.
  2. Enable its staging environment:
    cube data-model enable-branch <DEPLOYMENT_ID> team/my-branch
  3. Read the environment back:
    cube environments list <DEPLOYMENT_ID> --json
    json
    {
      "branch": "team/my-branch",
      "id": "<ENV_ID>",
      "type": "staging",
      "api_credentials": [
        {
          "type": "rest",
          "url": "https://cube.example.com/dev-mode/team%2Fmy-branch/cubejs-api/v1",
          "version": 1
        }
      ]
    }
  4. Request /meta against that URL with a token from cube deployments token <DEPLOYMENT_ID>.

Expected

The reported url serves the branch's data model.

Actual

It returns 400. Results for the same environment, same token:

URL Response
/staging/team/my-branch/cubejs-api/v1/meta 200 — branch model
/dev-mode/team%2Fmy-branch/cubejs-api/v1/meta (API-reported) 400 {"statusCode":400,"error":"BadRequestError: Bad branch"}
/staging/team%2Fmy-branch/cubejs-api/v1/meta 400 {"statusCode":400,"error":"BadRequestError: Bad branch"}
/cubejs-api/v1/meta (production, for comparison) 200 — production model

The /staging/ response returns a different cube count from production, confirming it is genuinely serving the branch's model.

So neither substitution alone fixes the API-reported URL: the path segment must be /staging/ and the branch must not be URL-encoded.

Not CLI-side

The same value comes back from the raw API, so this looks server-side rather than a CLI bug:

cube api GET /api/v1/deployments/<DEPLOYMENT_ID>/environments
→ "url": "https://cube.example.com/dev-mode/team%2Fmy-branch/cubejs-api/v1"

Why it matters

Anything programmatic — CI wiring a preview environment's cube URL into downstream services — naturally trusts the URL the API reports for the environment it just enabled. That URL 400s, so the correct behaviour is to ignore the API value and reconstruct <deploymentUrl>/staging/<branch>/cubejs-api/v1 by hand, which is fragile and non-obvious.

Also worth flagging as possibly related: the environment type is staging while the reported path segment says dev-mode, which is confusing independent of the 400.

Environment

  • Cube CLI 1.7.33 (installed via install-cli.sh, aarch64-apple-darwin)
  • Cube Cloud, eu-west-2
  • Branch registered in Cube (not only in the connected git remote)

Deployment id, hostname and branch name are redacted; happy to supply them privately if useful.