{"record":{"id":"f9412c68a39fcde4","repo":"zed-industries/zed","slug":"copilot-is-still-starting","errorCode":null,"errorMessage":"copilot is still starting","messagePattern":"copilot is still starting","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/copilot/src/copilot.rs","lineNumber":76,"sourceCode":"    Disabled,\n    Starting { task: Shared<Task<()>> },\n    Error(Arc<str>),\n    Running(RunningCopilotServer),\n}\n\nimpl CopilotServer {\n    fn as_authenticated(&mut self) -> Result<&mut RunningCopilotServer> {\n        let server = self.as_running()?;\n        anyhow::ensure!(\n            matches!(server.sign_in_status, SignInStatus::Authorized),\n            \"must sign in before using copilot\"\n        );\n        Ok(server)\n    }\n\n    fn as_running(&mut self) -> Result<&mut RunningCopilotServer> {\n        match self {\n            CopilotServer::Starting { .. } => anyhow::bail!(\"copilot is still starting\"),\n            CopilotServer::Disabled => anyhow::bail!(\"copilot is disabled\"),\n            CopilotServer::Error(error) => {\n                anyhow::bail!(\"copilot was not started because of an error: {error}\")\n            }\n            CopilotServer::Running(server) => Ok(server),\n        }\n    }\n}\n\nstruct RunningCopilotServer {\n    lsp: Arc<LanguageServer>,\n    sign_in_status: SignInStatus,\n    registered_buffers: HashMap<EntityId, RegisteredBuffer>,\n}\n\n#[derive(Clone, Debug)]\nenum SignInStatus {\n    Authorized,","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/copilot/src/copilot.rs#L58-L94","documentation":"The Copilot integration models its language-server lifecycle as the CopilotServer enum: Starting, Disabled, Error, Running. Almost every operation funnels through as_running()/as_authenticated(), and while the npm package is still being installed/downloaded and the language server process has not finished launching, the state is Starting and any request (completions, sign-in, register_buffer) bails with 'copilot is still starting'. This is a transient state error: the same call typically succeeds once startup completes.","triggerScenarios":"Calling any Copilot API (e.g. sign_in, register_buffer, completion requests) through methods that use as_running() during the window after the agent is created but before start_copilot's install+spawn task moves the state to Running — first use in a session, slow network on first download of the npm package.","commonSituations":"Cold start: first Copilot request right after editor launch before the @github/copilot-language-server package downloads; slow npm registry or offline machine stretching the Starting phase; tests invoking completion immediately after initializing the Copilot agent.","solutions":["Wait for startup to finish and retry the operation — the state advances automatically once the language server process is up","Trigger the download early (open the Copilot UI/sign-in flow once) so the package is cached before you need completions","Check network/npm-registry access if Starting persists for minutes (the underlying install may be silently slow or failing and will surface as the Error state)","In code that drives Copilot programmatically, gate requests on status()/language_server() being ready instead of calling immediately"],"exampleFix":"// before\nlet status = copilot.update(cx, |c, cx| c.sign_in(cx))?; // may hit Starting\n\n// after\nif copilot.read(cx).language_server().is_none() {\n    // wait / show 'starting' UI instead of invoking\n}\nlet task = copilot.update(cx, |c, cx| c.sign_in(cx));","handlingStrategy":"retry","validationCode":"// gate on readiness before invoking Copilot APIs\nif copilot.read(cx).language_server().is_none() {\n    // still Starting (or Disabled/Error) — defer the call\n    return Task::ready(Err(anyhow!(\"copilot not ready yet\")));\n}\ncopilot.update(cx, |c, cx| c.sign_in(cx))","typeGuard":"fn copilot_ready(copilot: &Entity<Copilot>, cx: &App) -> bool {\n    copilot.read(cx).language_server().is_some() // Some only when Running\n}","tryCatchPattern":"// state error, not a value error: catch, check, wait for the state change, retry\nmatch result {\n    Err(err) if err.to_string().contains(\"copilot is still starting\") => {\n        // re-run after the startup task notifies; don't spawn tight-loop retries\n        retry_after_state_change(copilot).await\n    }\n    other => other,\n}","preventionTips":["Observe the Copilot entity and drive UI off status() instead of calling APIs blind","Warm the download early in a session so the Starting window is short","Treat persistent Starting as an install problem in progress — check network, not the API call"],"tags":["copilot","lifecycle","startup","transient","language-server"],"backgroundTag":"service-not-ready-yet","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}