# SDK can't start a chat with a self-hosted "My Machines" worker

**URL:** <https://forum.cursor.com/t/sdk-cant-start-a-chat-with-a-self-hosted-my-machines-worker/160136>\
**Category:** Bug Reports\
**Tags:** cursor-sdk, github, docs, cloud-agents\
**Created:** [May 8, 2026, 10:09pm UTC](https://forum.cursor.com/t/sdk-cant-start-a-chat-with-a-self-hosted-my-machines-worker/160136 "2026-05-08T22:09:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_M](https://sea3.discourse-cdn.com/cursor1/user_avatar/forum.cursor.com/james_m/32/86150_2.png) [@James\_M](https://forum.cursor.com/u/James_M)\
**Post date:** [May 8, 2026, 10:09pm UTC](https://forum.cursor.com/t/sdk-cant-start-a-chat-with-a-self-hosted-my-machines-worker/160136/1 "2026-05-08T22:09:10Z")

</div>

### Where does the bug appear (feature/product)?

Somewhere else…

### Describe the Bug

**The bug appears in the TypeScript SDK**

The TypeScript SDK’s typing for CloudAgentOptions and the server’s actual validation behavior disagree, with no examples in the docs to clarify intent for self-hosted “machine” workers. Three concrete issues:

### Bug 1: `repos` is required

repos is typed as optional but enforced as required. `node_modules/@cursor/sdk/dist/esm/options.d.ts` declares `repos?: Array<{ url: string; startingRef?: string; prUrl?: string }>` (with ?), so omitting it is type-legal.

At runtime the server returns

> `[repository_required] Repository is required. Either provide a repository URL in the repos[0].url field, or configure a default repository at https://cursor.com/settings.`

### Bug 2: `startingRef` is required

`startingRef` is typed as optional but enforced as required (with no fallback). Same .d.ts declares `startingRef?: string`. The docs at [Cursor TypeScript SDK | Cursor Documentation](https://cursor.com/docs/sdk/typescript#cloudoptions) also list it as optional. Omitting it returns

> `[validation_error] Failed to determine repository default branch. There's no documented way to ask the server to look up the repo's default branch.`

### Bug 3: GitHub branch validation?

Self-hosted “machine” path requires GitHub branch validation that the dashboard skips. When cloud.env.type is “machine” (a registered “My Machines” worker), the worker has its own local checkout. Starting a chat against the same worker from [https://cursor.com/agents](https://cursor.com/agents) (worker dropdown) succeeds without any GitHub integration. But the SDK’s Agent.create({ cloud: { env: { type: “machine”, name }, repos: [{ url, startingRef }] } }) calls `POST /v1/agents` which always validates the branch against GitHub via the Cursor GitHub App, returning

> `[validation_error] Failed to verify existence of branch '<name>' in repository/<org>/<repo>`

even when the branch demonstrably exists on the remote (which is a public repo) — the underlying cause is presumably that the org hasn’t authorized the Cursor GitHub App. The dashboard’s “My Machines” chat path clearly uses a different API that doesn’t run this validation.

Also worth noting: the official cursor/plugins#cursor-sdk skill (the canonical SDK documentation source) contains zero examples using env.type: “machine” — only cloud and pool. So it’s hard to know how to use it and perhaps that’s why I’m running into issues.

### Steps to Reproduce

1. Have a “My Machines” worker registered: agent worker start --name foo from a checkout of a repo whose org has not authorized the Cursor GitHub App.
2. From a separate Node process, install `@cursor/sdk` and run:

```auto
import { Agent } from "@cursor/sdk";
const agent = await Agent.create({
  apiKey: process.env.CURSOR_API_KEY!,
  cloud: { env: { type: "machine", name: "foo" } },
});
await agent.send("hello");

```

1. Observe `[repository_required]` error.
2. Add repos: [{ url: “`https://github.com/<org>/<repo>`” }] (no startingRef).
3. Observe `[validation_error] Failed to determine repository default branch`.
4. Add `startingRef: "main"` (a branch that exists on the remote).
5. Observe `[validation_error] Failed to verify existence of branch 'main' in repository <org>/<repo>`.
6. Open [https://cursor.com/agents](https://cursor.com/agents) in the same Cursor account, pick the same worker from the dropdown, send the same message. Works immediately, no GitHub integration needed.

### Expected Behavior

For self-hosted machine workers (env.type: “machine”):

- Either the SDK should match the dashboard’s behavior and skip GitHub-side branch validation (the worker has its own checkout; the cloud doesn’t need to clone or validate anything).
- Or, at minimum, the docs and .d.ts should make it explicit that repos and startingRef are required for type: “machine” and that the org must have the Cursor GitHub App installed even though no cloning happens.

### Operating System

Linux

### Version Information

Version: 3.3.27  
VSCode Version: 1.105.1  
Commit: 80b138a7a0a948e1a798e9ed7867d76a1ba9a310  
Date: 2026-05-08T02:26:22.498Z  
Layout: editor  
Build Type: Stable  
Release Track: Default  
Electron: 39.8.1  
Chromium: 142.0.7444.265  
Node.js: 22.22.1  
V8: 14.2.231.22-electron.0  
OS: Linux x64 6.17.0-22-generic

### Does this stop you from using Cursor

No - Cursor works, but with this issue

---

<div class="post-metadata">

**Author:** ![deanrie](https://sea3.discourse-cdn.com/cursor1/user_avatar/forum.cursor.com/deanrie/32/1263_2.png) [@deanrie](https://forum.cursor.com/u/deanrie)\
**Post date:** [May 9, 2026, 7:38am UTC](https://forum.cursor.com/t/sdk-cant-start-a-chat-with-a-self-hosted-my-machines-worker/160136/5 "2026-05-09T07:38:26Z")

</div>

Hey, thanks for such a detailed report. The three symptoms, plus the contrast with the dashboard behavior, plus the types from the .d.ts file are super helpful.

Confirmed, this is real behavior. The SDK path `POST /v1/agents` for `env.type: "machine"` runs repo and branch validation through the Cursor GitHub App, while the dashboard My Machines uses a different path and trusts the worker itself about its checkout. That’s why you see the mismatch. The mismatch between the SDK types and the docs (`repos?`, `startingRef?`) vs the server’s real behavior for `type: "machine"` is also a valid point, and so is the lack of `machine` examples in the SDK skill.

I’ve reported this internally and linked this thread. I can’t share an ETA for a fix yet. When something moves, we’ll reply here.

Workaround for now, so the SDK can still start a chat against a `machine` worker:

- Pass `repos: [{ url, startingRef }]` explicitly, even if the dashboard logic makes this feel redundant for machine.
- Use a repo in an org where the Cursor GitHub App is authorized, or a public repo with a valid branch that the GitHub App can see.
- If neither works, the dashboard path [cursor.com/agents](http://cursor.com/agents) is currently the only one that doesn’t require GitHub-side validation for machine workers.

If you hit more edge cases when using machine workers via the SDK, drop them in this same thread.
