microsoft/TypeScript · error · Error

LanguageService Operation: ${key} not allowed in LanguageSer

Error message

LanguageService Operation: ${key} not allowed in LanguageServiceMode.PartialSemantic

What it means

Thrown by a LanguageService created in LanguageServiceMode.PartialSemantic when you call an operation that requires full semantic analysis. On creation, createLanguageService walks the invalidOperationsInPartialSemanticMode list (getSemanticDiagnostics, getSuggestionDiagnostics, getCompilerOptionsDiagnostics, getSemanticClassifications, getEncodedSemanticClassifications, getCodeFixesAtPosition, getCombinedCodeFix, applyCodeActionCommand, organizeImports, getEditsForFileRename, getEmitOutput, getApplicableRefactors, getEditsForRefactor, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, getSupportedCodeFixes, getPasteEdits) and overwrites each method on the ls object with a thunk that throws. The mode is selected by the third argument to createLanguageService. PartialSemantic mode is intentionally a faster, lighter service that forgoes type info, so those calls are hard-disabled rather than silently returning stale/empty data.

Source

Thrown at src/services/services.ts:3464

        provideCallHierarchyOutgoingCalls,
        toggleLineComment,
        toggleMultilineComment,
        commentSelection,
        uncommentSelection,
        provideInlayHints,
        getSupportedCodeFixes,
        preparePasteEditsForFile,
        getPasteEdits,
        mapCode,
    };

    switch (languageServiceMode) {
        case LanguageServiceMode.Semantic:
            break;
        case LanguageServiceMode.PartialSemantic:
            invalidOperationsInPartialSemanticMode.forEach(key =>
                ls[key] = () => {
                    throw new Error(`LanguageService Operation: ${key} not allowed in LanguageServiceMode.PartialSemantic`);
                }
            );
            break;
        case LanguageServiceMode.Syntactic:
            invalidOperationsInSyntacticMode.forEach(key =>
                ls[key] = () => {
                    throw new Error(`LanguageService Operation: ${key} not allowed in LanguageServiceMode.Syntactic`);
                }
            );
            break;
        default:
            Debug.assertNever(languageServiceMode);
    }
    return ls;
}

/**
 * Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`.

View on GitHub (pinned to b465fdbfe1)

Solutions

  1. If you need the failing feature, create the LanguageService in the default Semantic mode by passing undefined (or LanguageServiceMode.Semantic) as the third argument to createLanguageService.
  2. Keep two LanguageService instances: a PartialSemantic one for fast syntactic operations and a Semantic one for diagnostics/codefixes/emit/inlay hints, and route each call to the appropriate instance.
  3. Before calling, check the mode you passed at creation; gate the call behind a guard that only runs semantic operations on a Semantic-mode service.
  4. If you are a tsserver/LS host author, confirm you are not forwarding requests (quickinfo, diagnostics, codefix) to a server configured for PartialSemantic / syntacticOnly.

Example fix

// before
const ls = ts.createLanguageService(host, registry, ts.LanguageServiceMode.PartialSemantic);
ls.getSemanticDiagnostics(file); // throws

// after
const ls = ts.createLanguageService(host, registry, ts.LanguageServiceMode.Semantic);
ls.getSemanticDiagnostics(file);
Defensive patterns

Strategy: validation

Validate before calling

// Before creating the service, decide whether you need semantic features.
const NEEDS_SEMANTIC = true; // diagnostics, codefixes, emit, inlay hints
const mode = NEEDS_SEMANTIC
  ? ts.LanguageServiceMode.Semantic
  : ts.LanguageServiceMode.PartialSemantic;
const ls = ts.createLanguageService(host, registry, mode);

Type guard

// Operations permitted in PartialSemantic mode (everything NOT in
// invalidOperationsInPartialSemanticMode, services.ts:1585).
const PARTIAL_SEMANTIC_BLOCKED = new Set([
  "getSemanticDiagnostics","getSuggestionDiagnostics","getCompilerOptionsDiagnostics",
  "getSemanticClassifications","getEncodedSemanticClassifications",
  "getCodeFixesAtPosition","getCombinedCodeFix","applyCodeActionCommand",
  "organizeImports","getEditsForFileRename","getEmitOutput","getApplicableRefactors",
  "getEditsForRefactor","prepareCallHierarchy","provideCallHierarchyIncomingCalls",
  "provideCallHierarchyOutgoingCalls","provideInlayHints","getSupportedCodeFixes","getPasteEdits",
] as const);
function isAllowedInPartialSemantic(op: string): boolean {
  return !PARTIAL_SEMANTIC_BLOCKED.has(op as any);
}

Try / catch

// Not recommended: the throw is a programming error, not a runtime hazard.
// Prefer creating the service in Semantic mode. If you must defend:
try {
  ls.getSemanticDiagnostics(file);
} catch (e) {
  if (e instanceof Error && /not allowed in LanguageServiceMode\.PartialSemantic/.test(e.message)) {
    // route to a Semantic-mode service instead
  } else throw e;
}

Prevention

When it happens

Trigger: Calling createLanguageService(host, documentRegistry, LanguageServiceMode.PartialSemantic) and then invoking any of the listed semantic methods, e.g. ls.getSemanticDiagnostics(file), ls.getCodeFixesAtPosition(...), ls.organizeImports(...), ls.getEmitOutput(file), ls.getApplicableRefactors(...), ls.provideInlayHints(...), or ls.getPasteEdits(...). The key interpolated into the message is the exact method name you called.

Common situations: Editors or language tooling that opt into PartialSemantic (syntax+partial) mode for speed on large projects, then reuse the same ls handle for diagnostics/codefixes/emit that used to work under the default Semantic mode. Migrating a host that previously passed undefined (defaults to Semantic) to an explicit PartialSemantic value. Sharing one ls between a syntactic fast-path and a semantic feature without checking the mode.

Related errors


AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12). Data as JSON: /api/errors/7cb9932bb242609a. Report an issue: GitHub.