neoclide/coc.nvim · info · CancellationError

Request cancelled

Error message

Request cancelled

What it means

Identical family to the RequestCancelled path: for server responses with code -32800/-32802 and no attached data, the client throws a plain CancellationError. Callers using CancellationToken-based APIs should expect this as normal control flow, not a failure.

Source

Thrown at src/language-client/client.ts:1946

    SemanticTokensRequest.method,
    SemanticTokensRangeRequest.method,
    SemanticTokensDeltaRequest.method
  ])

  public handleFailedRequest<T, P extends { method: string }>(type: P, token: CancellationToken | undefined, error: any, defaultValue: T, showNotification = true): T {
    if (token && token.isCancellationRequested) return defaultValue
    // If we get a request cancel or a content modified don't log anything.
    if (error instanceof ResponseError) {
      // The connection got disposed while we were waiting for a response.
      // Simply return the default value. Is the best we can do.
      if (error.code === ErrorCodes.PendingResponseRejected || error.code === ErrorCodes.ConnectionInactive) {
        return defaultValue
      }
      if (error.code === LSPErrorCodes.RequestCancelled || error.code === LSPErrorCodes.ServerCancelled) {
        if (error.data != null) {
          throw new LSPCancellationError(error.data)
        } else {
          throw new CancellationError()
        }
      } else if (error.code === LSPErrorCodes.ContentModified) {
        if (BaseLanguageClient.RequestsToCancelOnContentModified.has(type.method)) {
          throw new CancellationError()
        } else {
          return defaultValue
        }
      }
    }
    this.error(`Request ${type.method} failed.`, error, showNotification)
    throw error
  }
  /**
   * @internal
   */

  // Should be kept
  public logFailedRequest(type: any, error: any): void {

View on GitHub (pinned to 50e974d969)

Solutions

  1. Handle CancellationError explicitly and return a default/empty result
  2. Re-invoke the request with a fresh token if the result is still needed
  3. Pass a linked CancellationToken so cancellation propagates predictably
  4. Enable request debouncing in the calling feature to reduce cancellations

Example fix

// before
const hover = await sendHover(token)
// after
const hover = await sendHover(token).catch(e => {
  if (e instanceof CancellationError) return null
  throw e
})
Defensive patterns

Strategy: try-catch

Validate before calling

if (token.isCancellationRequested) return defaultValue

Type guard

function isCancellationError(e: unknown): e is CancellationError {
  return e instanceof CancellationError || (e as any)?.name === 'Canceled'
}

Try / catch

try {
  return await sendRequest(type, params, token)
} catch (e) {
  if (isCancellationError(e)) return defaultValue // cancellation is control flow
  throw e
}

Prevention

When it happens

Trigger: sendRequest receives error code -32800 (RequestCancelled) or -32802 (ServerCancelled) with error.data == null, so the generic CancellationError is thrown from handleRequestError.

Common situations: CancellationToken fired before the server answered; server-side queue eviction of concurrent requests; feature providers (completion, signature help) racing during fast typing.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/bcfc33e72d53d233. Report an issue: GitHub.