Our API is at /api on the same origin. I expected the /api suffix to be there. It is a Next app; the only Express in the repo is a small socket server in another package.
Environment detection checks whether any manifest in scope depends on express. If one does, it runs a .listen() port heuristic to find the API origin, and when that heuristic finds nothing usable it falls back to http://localhost:3000 — which happens to be what ui already is. Crucially, taking that branch skips the default that would otherwise have set api to the UI base URL plus /api. So one unrelated package in the workspace changes the answer for the whole proposal.
Open issue. The fix on your side is one line per environment:
yaml
api:
baseUrl: http://localhost:3000/api
Do it before you write features, because the failure is downstream and confusing — the request succeeds, returns the app shell, and you get a JSON parse error or a schema mismatch rather than anything that points at configuration.
Quick check for anyone reading this later, run it right after --apply:
bash
grep -n 'baseUrl' projects/<slug>/envs/*.yaml
If ui and api are byte-identical, you are in this bug. Ours was, and we have no Express at all in the app — it came in through a dev dependency of a tool package.