stablyai / stablyai/orca

[Bug]: A control frame with no id kills the terminal daemon and every terminal on the host

Open
#17,841 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
70.4k
Forks
4.6k
Avg merge
16h 8m
Merged PRs (30d)
451

Description

**Operating system:** Linux (observed on Synology DSM; the code path has no platform branch)
**Orca version:** built from `main` at `94e758666` — between v1.4.191 and v1.4.192

---

One control frame whose `id` is missing or not a string takes the terminal daemon
down, and every terminal on the host with it — the process deliberately kept alive
so terminals outlive the runtime, the supervisor and an update.

`DaemonServer.handleRequest` reads `request.id` one line above the try/catch that
is already there:

```ts
const isNotify = request.id.startsWith(NOTIFY_PREFIX) // outside the try
try { ... }
```

That throws a TypeError, escapes as an unhandled rejection, reaches the daemon's
`uncaughtException` handler, and is rethrown because it is not a native PTY error.

**Repro:**

1. Connect to the daemon's control socket.
2. Write one NDJSON line that is valid JSON with no usable id — `{}`, `null`, or
`{"id": 123}`.
3. The daemon exits. Every terminal on the host dies with it.

**Three places independently allow it:** the NDJSON boundary
(`createNdjsonParser` hands through any parsed JSON, `null` included, and the
callback asserts `as DaemonRequest` over it), the dispatch site
(`void this.handleRequest(...)` lets any rejection escape), and the id read
itself.

An unknown *method* is fine and already gets an error reply — that path was never
the problem. Only an unroutable frame is fatal, and it cannot be replied to anyway
since correlation needs the id it did not carry.

Contributor guide

Open the contributing guide

Research direction

Start at DaemonServer.handleRequest and trace the createNdjsonParser callback plus the void this.handleRequest dispatch site. Reproduce with NDJSON frames containing {}, null, and {"id":123}; done means an unroutable frame no longer terminates the daemon or its host terminals, while existing unknown-method handling remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.