Cloud Agent does not auto-start `terminals` from repo-managed environment.json (Builds enabled)

Where does the bug appear (feature/product)?

Cloud Agent (GitHub, Slack, Web, Linear)

Describe the Bug

Official docs say that after an agent boots from a Build, Cursor runs start and then any configured terminals in a shared tmux session. I followed that contract with a repo-file managed .cursor/environment.json (no dashboard start box).

On this run the four terminals were never spawned:

  • no tmux sessions
  • declared ports 8790 / 8780 / 8770 / 8760 all CLOSED
  • no pnpm / wrangler / vite / astro processes
  • empty agent terminals directory
  • no /tmp/cursor/start-user/ logs at all

This does not look like the commands crashing. If they had started and failed, I would still expect tmux panes, PIDs, or logs. Nothing was launched.

Docs I followed:

  • https://cursor.com/docs/cloud-agent/setup — “After an agent boots from a Build, Cursor runs the start command and then any configured terminals.”
  • https://cursor.com/docs/cloud-agent/buildsterminals run “At the start of each agent run”
  • https://cursor.com/schemas/environment.schema.jsonterminals: “The terminals to run when the environment is started.”

I omitted start on purpose (You can skip start in many repos). Long-running foreground dev servers are in terminals, not install. install only installs deps.

.cursor/environment.json (committed on default branch dev)

{
  "install": "bash .cursor/install.sh",
  "ports": [
    { "name": "docs", "port": 8790 },
    { "name": "admin-api", "port": 8780 },
    { "name": "admin-web", "port": 8770 },
    { "name": "blog-public", "port": 8760 }
  ],
  "terminals": [
    {
      "name": "docs",
      "command": "bash -lc 'pnpm --filter docs dev'",
      "description": "Starlight docs (pnpm dev:docs) on :8790"
    },
    {
      "name": "admin-api",
      "command": "bash -lc 'pnpm --filter admin-api dev'",
      "description": "Admin API Vite+Workers (pnpm dev:admin-api) on :8780"
    },
    {
      "name": "admin-web",
      "command": "bash -lc 'pnpm --filter admin-web dev'",
      "description": "Admin UI react-router (pnpm dev:admin-web) on :8770"
    },
    {
      "name": "blog-public",
      "command": "bash -lc 'pnpm --filter blog-public dev'",
      "description": "Public site (pnpm dev:public) on :8760"
    }
  ]
}

Notes:

  • Schema-valid name / command / description
  • bash -lc is only so a login shell picks up fnm/pnpm from ~/.bashrc
  • Required Dashboard Secrets were already injected at agent start (Hyperdrive + Supabase). Missing processes, not secrets.

What actually ran

/tmp/cursor/async-install/install-user.log:

>>> [install:] start
Started from stale build bld-20260819-51f4c31b-9aa9-4336-818f-8ec00de302b5, skipping install script
<<< [install:] complete

install-user.status = 0 (expected for a Build reuse). Skipping install should not skip terminals.

Also missing:

  • /tmp/cursor/start-user/ (directory does not exist)
  • tmux ls → no sessions
  • /home/ubuntu/.cursor/projects/workspace/terminals/ → empty

Port recheck after ~20 minutes:

127.0.0.1:8790 CLOSED
127.0.0.1:8780 CLOSED
127.0.0.1:8770 CLOSED
127.0.0.1:8760 CLOSED

Extra anomaly

cursor-cloud MCP environment-info returned environmentJson: null with:

environment.json contents are unavailable for this environment (it may have no stored environment.json, or the contents could not be loaded).

The file exists and is valid in the workspace. Possibly related to terminals not being scheduled.


中文摘要:

按官方 Setup / Builds 文档,repo 里的 terminals 应在每次 Cloud Agent 启动时自动用 tmux 拉起。本仓库 .cursor/environment.json 已按 schema 配置 4 个服务。实际这次 run(bc-a6e204ed-d3ab-4756-9f63-7ba3e84fba2f)开机 20 分钟后:无 tmux、四端口全关、无对应进程、无 start 日志。不像命令失败,而是平台没有调度 terminals

Steps to Reproduce

  1. Commit a repo-managed .cursor/environment.json with install + ports + terminals, no start.
  2. Enable Builds and run a successful manual Build.
  3. Start a new Cloud Agent from that Build on cursor.com (web, warmFork=cold, gitSetup=reuse).
  4. Do not ask the agent to start the apps.
  5. On the VM, check tmux ls, whether the declared ports LISTEN, and whether terminal sessions exist.

Expected Behavior

The platform should create four named tmux sessions, run the configured commands, and listen on 8790/8780/8770/8760 at agent start. The user should not have to prompt the agent to start them.

Screenshots / Screen Recordings

Operating System

Linux

Version Information

Version: 3.16.29
VS Code Extension API: 1.128.0
Commit: 6246455961129c32969845e00aa25d87ae926ec0
Date: 2026-08-18T01:26:26.285Z
Layout: IDE
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.291
OS: Linux x64 7.1.8-200.fc44.x86_64

For AI issues: which model did you use?

cursor-grok-4.6-high-fast

For AI issues: add Request ID with privacy disabled

bc-a6e204ed-d3ab-4756-9f63-7ba3e84fba2f

IDs (please look these up)

  • Agent: https://cursor.com/agents/bc-a6e204ed-d3ab-4756-9f63-7ba3e84fba2f
  • bcId: bc-a6e204ed-d3ab-4756-9f63-7ba3e84fba2f
  • Source: web
  • Model: cursor-grok-4.6-high-fast
  • Repo: github.com/superAlibi/astro_blog
  • Default branch / checkout: dev @ 7dc8c8a7358bc12e16067fbca5844a7cbc8e3a59
  • Environment: https://cursor.com/dashboard/cloud-agents/environments/e/30a7b16e-9bd9-11f1-ba66-0e7d0216e441
  • environmentPublicId: 30a7b16e-9bd9-11f1-ba66-0e7d0216e441
  • environmentVersionPublicId: 30af886a-9bd9-11f1-ba66-0e7d0216e441
  • Config source: source: Repository, environmentJsonPath: .cursor/environment.json
  • recordedVia: DASHBOARD
  • Build: bld-20260819-51f4c31b-9aa9-4336-818f-8ec00de302b5 (SUCCEEDED, MANUAL, WEBSITE)
  • gitSetup / warmFork: reuse / cold
  • setupStatus: null
  • First check: 2026-08-19 14:47 UTC; recheck 15:07 UTC still down; VM uptime ~20 min

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the detailed report. The config, logs, and IDs really helped us figure this out fast.

We found the issue. Right now, the terminals from environment.json only get set up on startup if your config also includes start. The platform ties launching tmux terminals to the start step, so if it is missing, your 4 sessions simply never get scheduled. This is not a problem with your config.

Workaround until it is fixed. Add any start, even a no-op, and the terminals will come up on every boot:

{
  "install": "bash .cursor/install.sh",
  "start": "true",
  "ports": [ ... ],
  "terminals": [ ... ]
}

I passed this to the team. I cannot share a timeline yet, but I will reply in the thread when I have an update. Let me know if the workaround helps.

Thank you for the guidance. The service has now started normally.

Follow-up: start is present and succeeds; terminals are still never scheduled

Where does the bug appear (feature/product)?

Cloud Agent (Web). Repo-managed .cursor/environment.json, Dockerfile base, Builds enabled.

Describe the Bug

Same symptom as the OP, after applying the workaround in post 5 of this thread (start required, even a no-op).

Docs (Cloud Agent Setup, Builds, and the published environment schema) say: after an agent boots from a Build, Cursor runs start, then any configured terminals in a shared tmux session.

We already have a real start (not only "start": "true"). On this run it completed with status 0. cursor-cloud MCP environment-info shows the stored environmentJson includes the terminals array (two named app processes).

The platform still never scheduled them:

  • no start:configure-terminals (MCP get-events returned 0 events)

  • /tmp/cursor/ contains only start-user/ — no configure-terminals job

  • start-user.sh is exactly the start command; nothing appends terminals

  • no tmux server (TMUX / TMUX_TMPDIR unset; /tmp/tmux-1000 empty; tmux list-windows -aerror connecting to /tmp/tmux-1000/default)

  • declared app ports connection refused

  • no configured terminal commands running

  • exec-daemon was started with --tmux-service-enabled and never created a session

This is not the commands crashing. If they had started and failed we would still expect tmux panes, PIDs, or a configure-terminals log. Nothing was launched.

The OP’s missing-start case had no /tmp/cursor/start-user/. We do have that directory, and start succeeded. Tying terminals to “start exists” is not sufficient on this runner.

Manual check: running the two terminals commands in a normal shell brought the app ports up. The commands themselves are fine.

.cursor/environment.json

Schema-valid name / command / description. install + start + terminals + ports. Dockerfile base (build.dockerfile relative to .cursor).

{
  "user": "ubuntu",
  "build": {
    "dockerfile": "cloud-agents/Dockerfile",
    "context": ".."
  },
  "install": ".cursor/cloud-agents/install.sh",
  "start": ".cursor/cloud-agents/start.sh",
  "terminals": [
    {
      "name": "api",
      "command": "pnpm dev:server",
      "description": "API on localhost"
    },
    {
      "name": "client",
      "command": "pnpm dev:client",
      "description": "Vite client on localhost"
    }
  ],
  "ports": [
    { "name": "api", "port": 5001 },
    { "name": "client", "port": 5273 }
  ]
}

Notes:

  • Real file also has extra published ports for local Docker services. Omitted here.

  • start.sh starts dockerd + Compose, then exits 0. It does not start the app processes; those are the terminals.

  • install only installs dependencies.

  • Wrapping the terminal commands with a PATH snippet does not matter: the commands were never invoked.

What actually ran

/tmp/cursor/start-user/start-user.sh:

.cursor/cloud-agents/start.sh

/tmp/cursor/start-user/start-user.status = 0

start-user.log reached [start] infra ready. Compose services that start owns were healthy.

Immediately after that, and again after the agent had been up, the terminals ports were connection refused.

/tmp/cursor tree:

/tmp/cursor
/tmp/cursor/start-user
/tmp/cursor/start-user/start-user.log
/tmp/cursor/start-user/start-user.sh
/tmp/cursor/start-user/start-user.status

No /tmp/cursor/async-install/ on this agent (expected: Build reuse). No other start-* job.

MCP

  • environment-info: stored environmentJson includes terminals.

  • get-events: empty (0 events). No start:configure-terminals.

  • Contrast with the OP, where environment-info returned environmentJson: null. Ours loaded and still did not schedule terminals.

Steps to Reproduce

  1. Commit a repo-managed .cursor/environment.json with Dockerfile build, install, a real start that exits 0, ports, and terminals.

  2. Create / use a Builds-enabled environment from that branch. Wait for a successful Dockerfile Build.

  3. Start a new Cloud Agent from that Build (web). Do not ask the agent to start the apps.

  4. Confirm start ran: /tmp/cursor/start-user/start-user.status is 0.

  5. On the VM check tmux list-windows -a, find /tmp/cursor, MCP get-events, and whether the terminals ports LISTEN.

Expected Behavior

After start exits 0, the platform should create the named tmux sessions (or windows on the shared session), run the configured terminals commands, and listen on those ports. The user should not have to start those processes by hand.

Operating System

Linux (Cloud Agent VM). Reporter desktop: macOS.

Version Information

Version: 3.20.17 VS Code Extension API: 1.128.0 Commit: 0c32194e3fb5ffaced9fb36430b860ec301e1fc0 Date: 2026-09-12T03:16:10.634Z Layout: Agent Window Build Type: Stable Release Track: Nightly Electron: 42.10.0 Chromium: 148.0.7778.280 Node.js: 24.18.1 V8: 14.8.178.38-electron.0 xterm.js: 6.1.0-beta.291 OS: Darwin arm64 25.6.0

For AI issues: which model did you use?

Cloud Agent environment under test (web). Diagnosis also done from Cursor desktop.

For AI issues: add Request ID with privacy disabled

bc-5e95fb56-1ce5-4a06-b8c2-f1985038ac39

IDs (please look these up)

Does this stop you from using Cursor

No — Cursor works, but Cloud Agents do not bring up the app processes the docs assign to terminals. They can be started by hand after boot.

Hey, thanks for the detailed follow-up. The config, logs, MCP output, and ID really help.

You’re right that this is a different case from the original one in this thread. In that case, start was missing, and terminals weren’t being scheduled because of that. In your case, start is present, it completes with exit code 0, environmentJson includes terminals, but configure-terminals still doesn’t get scheduled (0 events, no tmux, ports are closed). So the workaround from post #5 (adding a no-op start) doesn’t apply here. The cause is different, and it’s not something in your config.

I’ve passed these details to the team along with your IDs. The key point is that you have Dockerfile-base and start succeeds, but terminals still don’t come up. I can’t share a timeline yet, but I’ll post an update in the thread as soon as I have one.

For now, as a temporary workaround, you can start the terminal commands manually after boot (you already confirmed the ports come up then), or bundle them into start.sh as background processes. Let me know if you try the second option and anything behaves unexpectedly.

For now, I have added instructions in AGENTS.md to start the apps in tmux windows similar to how terminals would do.

The agent can start the apps when needed. It works for me.

I will wait for the response.

Hey, thanks for getting back to me. It’s good that the temporary workaround via AGENTS.md is keeping things running.

We’re tracking your case separately from the original one in this thread. In that one, the cause was a missing start, but in your case start exists and finishes with exit 0, the terminals are present in environmentJson, but configure-terminals still doesn’t get scheduled (0 events, no tmux, ports are refused). So this is a different issue, and it’s not something in your configuration. I’ve passed the details and all the IDs to the team.

For now, stick with the manual start or bundling in start.sh as a temporary measure. I can’t share a timeline yet, but I’ll follow up as soon as there’s an update for your specific case. If you notice anything new along the way, like different behavior between cold vs warm boot, or between build reuse vs a fresh build, drop it here. It’ll help narrow down the cause.