Skip to content

[Bug] LSP freezes and diagnostics timeout too short (3s) for heavy language servers #13328

Closed

Description

@ojh102

Description

Multiple users are experiencing LSP-related freezes and timeouts across different scenarios:

Root Cause Analysis:

  1. Blocking initialization: getClients() blocks the UI thread when LSP servers are slow to start
  2. Insufficient timeout defaults: Diagnostics timeout was hardcoded at 3s — too short for heavy linters like ESLint and Kotlin LSP
  3. No user escape hatch: No way for users to configure timeouts for their specific environment

Related PRs:

PR Approach Status
#13332 Non-blocking init + configurable diagnostics timeout Open
#13281 Diagnostics timeout 3s→10s Open
#6997 Configurable per-server timeout via config Open
#13287 Startup package-manager timeout guard Open (independent)
#13299 UI freeze on large diffs Open (independent)

Resolution Path:

Addressed by PR #13332:

  • ✅ Non-blocking LSP initialization (getClients returns immediately)
  • ✅ Configurable diagnostics timeout (10s default, override via OPENCODE_EXPERIMENTAL_LSP_DIAGNOSTICS_TIMEOUT_MS)

Remaining work (separate concerns):

Plugins

No response

OpenCode version

dev (latest)

Steps to reproduce

  1. Open a project with a heavy LSP (e.g., Kotlin, ESLint with many plugins)
  2. Start OpenCode
  3. Observe: UI blocks during LSP initialization, and diagnostics timeout at 3s returning empty results for slow language servers

Screenshot and/or share link

No response

Operating System

Cross-platform (reported on macOS, Windows, Linux)

Terminal

Multiple terminals affected (not terminal-specific)

Activity

  1. added
    perfIndicates a performance issue or need for optimization
    on Feb 12, 2026
  2. andisolo commented on Mar 17, 2026

    @andisolo

    It's not a timeout issue.

    index.ts

    import * as net from 'net';
    
    const PORT = 9999;
    const HOST = '127.0.0.1';
    
    async function start() {
        const socket = new net.Socket();
        socket.on('close', () => {
            process.exit(0);
        });
        socket.on('error', (err) => {
            process.exit(1);
        });
        
        await new Promise<void>((resolve, reject) => {
            socket.connect(PORT, HOST, () => {
                resolve();
            });
            socket.on('error', reject);
        });
    
        process.stdin.pipe(socket);
        socket.pipe(process.stdout);
        process.stdin.resume();
    }
    
    start();
      "lsp": {
        "kotlin-ls": {
          "disabled": true
        },
        "kotlin-lsp": {
          "command": [
            "npx",
            "tsx",
            "path of index.ts"
          ],
          "extensions": [
            ".kt"
          ]
        }
      }

    can work for me (macOS).

  3. NightSling commented on Apr 2, 2026

    @NightSling

    Can someone implement the fix please? It's really hindering.

  4. Hona commented on Apr 23, 2026

    @Hona
    Member

    please try the latest again - should be good now
    its much faster now. the first load of the lsp may be slower but no weirder race conditions
    Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

perfIndicates a performance issue or need for optimization

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions