Cube Cloud API reports an unusable REST URL for branch staging environments (/dev-mode/ + URL-encoded branch → 400 "Bad branch")
- Dominant language
- Rust
- Stars
- 20.8k
- Forks
- 2.1k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 181
Description
### 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 --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 team/my-branch
```
3. Read the environment back:
```
cube environments list --json
```
```json
{
"branch": "team/my-branch",
"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 `.
### 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//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
`/staging//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.
Contributor guide
Research direction
Start by reproducing GET /api/v1/deployments//environments and compare its reported URL with the working Cube Cloud UI URL. Trace the environment URL construction and branch-path handling; done means staging environments return a usable /staging//cubejs-api/v1 URL that serves /meta successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100