neoclide/coc.nvim · error

`tokenType` is not in the provided legend

Error message

`tokenType` is not in the provided legend

What it means

When pushing a token with a string tokenType, the builder looks it up in the legend passed to the constructor. If the tokenType string is not present in the legend's tokenTypes array, it cannot be encoded and this error is thrown.

Source

Thrown at src/model/semanticTokensBuilder.ts:85

      // 1st overload
      return this._pushEncoded(arg0, arg1, arg2, arg3, arg4)
    }
    if (Range.is(arg0) && typeof arg1 === 'string' && isStrArrayOrUndefined(arg2)) {
      // 2nd overload
      return this._push(arg0, arg1, arg2)
    }
    throw new Error('Illegal argument')
  }

  private _push(range: Range, tokenType: string, tokenModifiers?: string[]): void {
    if (!this._hasLegend) {
      throw new Error('Legend must be provided in constructor')
    }
    if (range.start.line !== range.end.line) {
      throw new Error('`range` cannot span multiple lines')
    }
    if (!this._tokenTypeStrToInt.has(tokenType)) {
      throw new Error('`tokenType` is not in the provided legend')
    }
    const line = range.start.line
    const char = range.start.character
    const length = range.end.character - range.start.character
    const nTokenType = this._tokenTypeStrToInt.get(tokenType)!
    let nTokenModifiers = 0
    if (tokenModifiers) {
      for (const tokenModifier of tokenModifiers) {
        if (!this._tokenModifierStrToInt.has(tokenModifier)) {
          throw new Error('`tokenModifier` is not in the provided legend')
        }
        const nTokenModifier = this._tokenModifierStrToInt.get(tokenModifier)!
        nTokenModifiers |= (1 << nTokenModifier) >>> 0
      }
    }
    this._pushEncoded(line, char, length, nTokenType, nTokenModifiers)
  }

View on GitHub (pinned to 50e974d969)

Solutions

  1. Use the exact strings from the server's legend (fetch via the semanticTokensLegend registration)
  2. Add the missing token type to the builder's legend constructor options
  3. Guard with a check before pushing: if (!legend.tokenTypes.includes(type)) skip or log
  4. Derive the client legend from the server registration instead of hardcoding

Example fix

// before
const builder = new SemanticTokensBuilder({ tokenTypes: ['keyword','string'], tokenModifiers: [] })
builder.push(range, 'namespace') // throws
// after
const builder = new SemanticTokensBuilder({ tokenTypes: ['keyword','string','namespace'], tokenModifiers: [] })
Defensive patterns

Strategy: validation

Validate before calling

if (!legend.tokenTypes.includes(tokenType)) {
  console.warn(`Skipping token with unknown type ${tokenType}`)
  return
}

Type guard

function isKnownTokenType(t: string, legend: SemanticTokensLegend): boolean {
  return legend.tokenTypes.includes(t)
}

Try / catch

try {
  builder.push(range, tokenType, modifiers)
} catch (e) {
  if (e.message.includes('tokenType` is not in the provided legend')) {
    console.warn(`Unknown token type: ${tokenType}`)
  }
}

Prevention

When it happens

Trigger: Calling push(range, 'myTokenType', ...) where 'myTokenType' is not in the tokenTypes array supplied to new SemanticTokensBuilder({...}); typos or case mismatches between server legend and client legend.

Common situations: Server and client legends drift after adding a new token type on the server; hardcoding token type strings that differ from the server's SemanticTokensLegend; copy-pasting token names from another language's provider.

Related errors


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