Skip to content

Commit b957102

Browse files
committed
fix(opencode): isHealthy() must reject 401 to prevent stale-orphan adoption
The previous semantic 'response.statusCode === 401 || isHealthResponse(body)' allowed isHealthy() to return true even when the server rejected the manager's password. On IDE restart, this caused the new manager (with a fresh password Y2) to falsely adopt an orphan opencode-serve from the previous IDE session that was still running with the old password Y1. The SPA proxy then forwarded requests with Y2; opencode rejected with 401; the user saw 'Error: Unauthorized' loading the chat UI. Fix: only treat the server as healthy when it returns a parseable health body (200 OK with {healthy:true, version:...}). 401 now returns false so doStart() falls through to killStaleServer(), which SIGKILLs the orphan and spawns a fresh opencode-serve with the current password. If a future test or user genuinely needs 'adopt an external server with unknown password' semantic, the right path is to read the password from that external server's data dir / env, not to ignore auth failures.
1 parent 5594814 commit b957102

2 files changed

Lines changed: 3 additions & 3 deletions

File tree

src/vs/workbench/contrib/opencode/electron-main/opencodeServeManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ export class OpencodeServeManager
394394
): Promise<boolean> {
395395
try {
396396
const response = await this.readHealth(url, password);
397-
return response.statusCode === 401 || isHealthResponse(response.body);
397+
return isHealthResponse(response.body);
398398
} catch {
399399
return false;
400400
}

src/vs/workbench/contrib/opencode/test/electron-main/opencodeServeManager.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,11 @@ suite('OpencodeServeManager / health checks', () => {
421421
assert.strictEqual(await internals(manager).isHealthy(`http://127.0.0.1:${backend.port}`, undefined), true);
422422
});
423423

424-
test('isHealthy returns true on HTTP 401 (auth required = server alive)', async () => {
424+
test('isHealthy returns false on HTTP 401 (auth required but wrong credentials)', async () => {
425425
backend = await mockBackend({ status: 401 });
426426
manager = new TestableOpencodeServeManager(configuration(), new NullLogService());
427427

428-
assert.strictEqual(await internals(manager).isHealthy(`http://127.0.0.1:${backend.port}`, undefined), true);
428+
assert.strictEqual(await internals(manager).isHealthy(`http://127.0.0.1:${backend.port}`, undefined), false);
429429
});
430430

431431
test('isHealthy returns false on HTTP 500', async () => {

0 commit comments

Comments
 (0)