{"record":{"id":"b4c8eff1bb7a1e24","repo":"microsoft/typescript-go","slug":"failed-to-refresh-diagnostics-w","errorCode":null,"errorMessage":"failed to refresh diagnostics: %w","messagePattern":"failed to refresh diagnostics: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/lsp/server.go","lineNumber":321,"sourceCode":"\n\treturn fmt.Errorf(\"no file watcher exists with ID %s\", id)\n}\n\n// RefreshDiagnostics implements project.Client.\nfunc (s *Server) RefreshDiagnostics(ctx context.Context) error {\n\tif !s.clientCapabilities.Workspace.Diagnostics.RefreshSupport {\n\t\treturn nil\n\t}\n\n\tif err := ctx.Err(); err != nil {\n\t\treturn err\n\t}\n\n\t// Fire-and-forget: the client always returns null, and waiting for the response\n\t// can cause the server to hang if the client is slow or unresponsive.\n\t// Any response from the client will be silently ignored by the read loop.\n\tif err := sendClientRequestFireAndForget(s, lsproto.WorkspaceDiagnosticRefreshInfo, lsproto.NoParams{}); err != nil {\n\t\treturn fmt.Errorf(\"failed to refresh diagnostics: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// PublishDiagnostics implements project.Client.\nfunc (s *Server) PublishDiagnostics(ctx context.Context, params *lsproto.PublishDiagnosticsParams) error {\n\treturn sendNotification(s, lsproto.TextDocumentPublishDiagnosticsInfo, params)\n}\n\n// SendTelemetry implements project.Client.\nfunc (s *Server) SendTelemetry(ctx context.Context, telemetry lsproto.TelemetryEvent) error {\n\tif !s.telemetryEnabled {\n\t\tpanic(\"SendTelemetry called with telemetry disabled\")\n\t}\n\treturn sendNotification(s, lsproto.TelemetryEventInfo, telemetry)\n}\n","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/lsp/server.go#L303-L339","documentation":"RefreshDiagnostics (server.go:308-325) failed to send the fire-and-forget workspace/diagnostic/refresh request: the client advertised diagnostics refresh support, but queueing the outgoing server->client request onto the outgoing queue (s.send via outgoingQueue.Put with the background context) errored. Because the request is fire-and-forget, client-side failures never produce this error — only local send/queue failures do.","triggerScenarios":"The outgoing queue is closed/drained during server shutdown, the writer has failed (broken stream), or the background context is canceled while the message is queued. The refresh is sent without waiting for a response per the comment at server.go:317-319, so no client response error can be the cause.","commonSituations":"Refresh racing server shutdown; the editor closed the connection while a project reload triggered diagnostics refresh; test servers with in-memory pipes closed early.","solutions":["Treat as mostly benign: the refresh is optional UX; on send failure the client will re-pull diagnostics on the next change anyway.","If it recurs mid-session, check writer health — this error implies the outgoing queue could not accept the message (stream broken or shutting down).","Guard call sites so refresh failures never abort larger operations (they are advisory notifications).","During shutdown paths, skip or ignore the error when the background context is canceled."],"exampleFix":"// before\nif err := client.RefreshDiagnostics(ctx); err != nil { return err }\n// after: advisory refresh must not fail the operation\nif err := client.RefreshDiagnostics(ctx); err != nil {\n    log.Printf(\"diagnostics refresh skipped: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"// capability check mirrors the server's own guard\nfunc supportsRefresh(caps *lsproto.ResolvedClientCapabilities) bool {\n    return caps.Workspace.Diagnostics.RefreshSupport\n}\n\nif supportsRefresh(&clientCaps) {\n    if err := client.RefreshDiagnostics(ctx); err != nil {\n        log.Printf(\"diagnostics refresh failed: %v\", err)\n    }\n}","typeGuard":"func refreshSafe(ctx context.Context) bool {\n    return ctx.Err() == nil // avoid queueing refreshes during shutdown\n}","tryCatchPattern":"if err := client.RefreshDiagnostics(ctx); err != nil {\n    if ctx.Err() != nil || shuttingDown() {\n        // queue closed during teardown: expected, ignore\n        return nil\n    }\n    log.Printf(\"diagnostics refresh skipped: %v\", err)\n}","preventionTips":["Treat refresh requests as advisory; never let their failure abort an operation.","Avoid triggering refreshes once shutdown begins (ctx canceled).","If refreshes fail mid-session, check writer/stream health — the outgoing queue rejects messages only when broken or closing."],"tags":["lsp","diagnostics","shutdown","fire-and-forget"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}