# How to Debug KCL Configuration Issues Leveraging LSP Tools

> Debug KCL configuration issues efficiently using LSP tools. Get real-time diagnostics, inspect types, navigate definitions, and visualize mismatches in your IDE for faster problem-solving.

- Repository: [The KCL Programming Language/kcl](https://github.com/kcl-lang/kcl)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Use the KCL Language Server Protocol (LSP) implementation to receive real-time diagnostics, inspect inferred types via hover tooltips, navigate to symbol definitions, and visualize type mismatches through inlay hints directly within your IDE.**

The `kcl-lang/kcl` repository provides a sophisticated Language Server built on the **Salsa** incremental compilation framework that transforms your editor into a powerful debugging environment for configuration code. By leveraging LSP tools to debug KCL configuration issues, you can identify type mismatches, undefined attributes, and schema violations without leaving your development workflow. The server analyzes your code incrementally, providing immediate feedback through standard LSP endpoints defined in the `crates/tools/src/LSP/src/` directory.

## Core LSP Features for Debugging KCL Configurations

The KCL Language Server exposes several debugging capabilities through specific handler modules. Each feature maps to a dedicated Rust source file that processes LSP JSON-RPC requests.

### Real-Time Compile-Time Diagnostics

The [`diagnostic.rs`](https://github.com/kcl-lang/kcl/blob/main/diagnostic.rs) module runs the KCL driver on every file change and collects `Diagnostic` objects, pushing them to your editor as you type. When you debug KCL configuration issues leveraging LSP tools, this feature surface errors such as type mismatches or undefined schema attributes immediately. According to the source code in [`crates/tools/src/LSP/src/diagnostic.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/diagnostic.rs), the server converts internal compiler errors into LSP-compatible diagnostic formats that include precise line numbers and error codes.

### Type and Value Inspection via Hover

To understand why a specific value is inferred a certain way, the [`hover.rs`](https://github.com/kcl-lang/kcl/blob/main/hover.rs) handler responds to `textDocument/hover` requests by returning formatted strings containing the **type**, **value**, and associated **doc comments**. In [`crates/tools/src/LSP/src/hover.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/hover.rs), the implementation queries the Salsa database to resolve the semantic information for the symbol under the cursor, allowing you to verify that configuration values match expected schemas without executing the program.

### Symbol Navigation with Go-to-Definition

The [`goto_def.rs`](https://github.com/kcl-lang/kcl/blob/main/goto_def.rs) module resolves **AST node** `DefId` values through the Salsa query graph to locate the original declaration of any symbol. When you invoke "Go to Definition" in your editor, the server in [`crates/tools/src/LSP/src/goto_def.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/goto_def.rs) traces the symbol back to its source location, enabling rapid navigation through large configuration codebases to find where schemas are defined or where variables are originally assigned.

### Reference Analysis for Variable Propagation

To track how a configuration value propagates through your codebase, [`find_refs.rs`](https://github.com/kcl-lang/kcl/blob/main/find_refs.rs) walks the **reference graph** built during semantic analysis. This handler processes `textDocument/references` requests by querying the analysis results compiled in [`crates/tools/src/LSP/src/find_refs.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/find_refs.rs), returning every location where a specific variable or schema attribute is read or written, which is essential for debugging configuration drift or unintended mutations.

### Visual Type Annotations via Inlay Hints

The [`inlay_hints.rs`](https://github.com/kcl-lang/kcl/blob/main/inlay_hints.rs) module generates **inline type annotations** that appear directly in your editor buffer. By requesting `textDocument/inlayHint`, the server returns hints that display the concrete type of expressions that lack explicit type annotations. The implementation in [`crates/tools/src/LSP/src/inlay_hints.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/inlay_hints.rs) analyzes expression nodes to determine inferred types, making it immediately obvious where implicit type conversions or mismatches occur in your configuration.

### Automated Quick Fixes and Formatting

For rapid remediation, [`quick_fix.rs`](https://github.com/kcl-lang/kcl/blob/main/quick_fix.rs) suggests **CodeAction** objects based on patterns detected by the analyzer, such as adding missing imports or fixing common schema violations. Additionally, [`formatting.rs`](https://github.com/kcl-lang/kcl/blob/main/formatting.rs) executes the KCL formatter via `textDocument/formatting` requests to ensure consistent code style. Both modules in [`crates/tools/src/LSP/src/quick_fix.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/quick_fix.rs) and [`crates/tools/src/LSP/src/formatting.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/formatting.rs) integrate with the compiler's error recovery mechanisms to provide actionable fixes alongside diagnostics.

## The LSP Architecture: How Debug Information Is Generated

Understanding the underlying architecture helps you reason about why specific diagnostics appear or why navigation behaves unexpectedly.

### Virtual File System and State Management

The [`state.rs`](https://github.com/kcl-lang/kcl/blob/main/state.rs) module tracks open documents and creates a **virtual file system** that the compiler queries without touching the real disk. In [`crates/tools/src/LSP/src/state.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/state.rs), the `GlobalState` struct maintains a snapshot of all open files, enabling the LSP to provide diagnostics and completions even for unsaved changes. This virtual filesystem is crucial for incremental analysis, as it allows the Salsa framework to detect exactly which files have changed.

### Incremental Compilation with Salsa

Each edit triggers a Salsa query defined in [`compile.rs`](https://github.com/kcl-lang/kcl/blob/main/compile.rs) that rebuilds only the affected parts of the program. The [`crates/tools/src/LSP/src/compile.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/compile.rs) module executes the KCL driver incrementally, producing updated **diagnostics** and **symbol tables** in real time. This incremental approach ensures that hover information and go-to-definition targets remain accurate even as you modify complex configuration files with deep dependencies.

### Message Dispatch and Error Transformation

The [`dispatcher.rs`](https://github.com/kcl-lang/kcl/blob/main/dispatcher.rs) module routes incoming LSP JSON-RPC requests to the appropriate handler functions (hover, goto-def, etc.), while [`error.rs`](https://github.com/kcl-lang/kcl/blob/main/error.rs) defines a unified error type that transforms internal compiler errors into standardized LSP `Diagnostic` objects. In [`crates/tools/src/LSP/src/dispatcher.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/dispatcher.rs), the dispatch logic maps method names to handler modules, and [`crates/tools/src/LSP/src/error.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/error.rs) ensures that KCL-specific error codes are preserved in the LSP output for client-side filtering.

## Practical LSP Workflows for Debugging

Configure your editor to invoke these LSP capabilities using standard JSON-RPC requests. Below are minimal examples demonstrating how to interact with the KCL Language Server for debugging tasks.

### Enabling Real-Time Diagnostics in VS Code

Configure the KCL language server path and enable quick-fixes on save:

```json
// settings.json
{
  "kcl.languageServer.path": "kcl-lsp",
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

```

This configuration ensures that [`diagnostic.rs`](https://github.com/kcl-lang/kcl/blob/main/diagnostic.rs) runs on every change, and [`quick_fix.rs`](https://github.com/kcl-lang/kcl/blob/main/quick_fix.rs) suggestions are applied automatically, surfacing errors like "type mismatch" or "undefined schema attribute" inline.

### Inspecting Types with Hover Requests

Request type and value information for a specific position:

```typescript
{
  "method": "textDocument/hover",
  "params": {
    "textDocument": { "uri": "file:///project/app.k" },
    "position": { "line": 12, "character": 5 }
  }
}

```

The server returns a markdown formatted response showing the inferred type and value:

```json
{
  "contents": {
    "kind": "markdown",
    "value": "**type**: `int`\n**value**: `42`\n*Defined in schema `MySchema`*"
  }
}

```

### Navigating to Symbol Definitions

Jump to the declaration of a schema attribute:

```typescript
{
  "method": "textDocument/definition",
  "params": {
    "textDocument": { "uri": "file:///project/app.k" },
    "position": { "line": 24, "character": 10 }
  }
}

```

The response from [`goto_def.rs`](https://github.com/kcl-lang/kcl/blob/main/goto_def.rs) contains the URI and range of the definition, allowing your editor to open the exact line in [`crates/tools/src/LSP/src/goto_def.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/tools/src/LSP/src/goto_def.rs) where the symbol is declared.

### Tracking Variable Usage with References

Find all usages of a potentially misconfigured variable:

```typescript
{
  "method": "textDocument/references",
  "params": {
    "textDocument": { "uri": "file:///project/app.k" },
    "position": { "line": 8, "character": 3 },
    "context": { "includeDeclaration": true }
  }
}

```

This queries [`find_refs.rs`](https://github.com/kcl-lang/kcl/blob/main/find_refs.rs) to return a list of locations where the variable is read or written, helping you trace the propagation of configuration values across modules.

### Visualizing Implicit Types with Inlay Hints

Request inline type annotations for a specific range:

```typescript
{
  "method": "textDocument/inlayHint",
  "params": {
    "textDocument": { "uri": "file:///project/app.k" },
    "range": {
      "start": { "line": 0, "character": 0 },
      "end": { "line": 200, "character": 0 }
    }
  }
}

```

The server returns hint data that your editor renders as subtle annotations (e.g., `: int` or `: {str:str}`) next to expressions, revealing type mismatches that might not be obvious from the source code alone.

## Summary

- **Real-time diagnostics** from [`diagnostic.rs`](https://github.com/kcl-lang/kcl/blob/main/diagnostic.rs) surface compile-time errors immediately as you edit KCL files.
- **Hover inspection** via [`hover.rs`](https://github.com/kcl-lang/kcl/blob/main/hover.rs) reveals the exact type, value, and documentation for any symbol under your cursor.
- **Navigation features** in [`goto_def.rs`](https://github.com/kcl-lang/kcl/blob/main/goto_def.rs) and [`find_refs.rs`](https://github.com/kcl-lang/kcl/blob/main/find_refs.rs) allow you to trace symbol origins and track value propagation through complex configurations.
- **Inlay hints** from [`inlay_hints.rs`](https://github.com/kcl-lang/kcl/blob/main/inlay_hints.rs) display implicit types directly in the editor buffer, making type mismatches visually obvious.
- **Quick fixes** in [`quick_fix.rs`](https://github.com/kcl-lang/kcl/blob/main/quick_fix.rs) provide automated corrections for common configuration errors like missing imports.
- **Incremental compilation** powered by Salsa in [`compile.rs`](https://github.com/kcl-lang/kcl/blob/main/compile.rs) ensures these features remain responsive even in large codebases.

## Frequently Asked Questions

### What is the KCL Language Server and how does it help debug configurations?

The KCL Language Server is an LSP implementation built on the Salsa incremental compilation framework that runs inside your editor. It provides real-time analysis of your configuration code through features like diagnostics, hover tooltips, and go-to-definition, allowing you to identify type errors and schema violations without manually running the KCL compiler from the command line.

### How does the KCL LSP provide real-time error diagnostics?

The server monitors file changes through the [`state.rs`](https://github.com/kcl-lang/kcl/blob/main/state.rs) virtual file system and triggers incremental compilation via [`compile.rs`](https://github.com/kcl-lang/kcl/blob/main/compile.rs) on every edit. The [`diagnostic.rs`](https://github.com/kcl-lang/kcl/blob/main/diagnostic.rs) module converts internal compiler errors into LSP `Diagnostic` objects that are pushed to your editor immediately, displaying errors such as "undefined schema attribute" or "type mismatch" with precise line numbers and error codes.

### Can the KCL LSP help me understand why a variable has a specific type?

Yes. By sending a `textDocument/hover` request to the server, the [`hover.rs`](https://github.com/kcl-lang/kcl/blob/main/hover.rs) module queries the Salsa database to retrieve the inferred type, runtime value, and documentation for any symbol. This allows you to verify that configuration values match their expected schemas and understand how the compiler resolved the type for complex expressions.

### Why would I use inlay hints when debugging KCL configurations?

Inlay hints, provided by [`inlay_hints.rs`](https://github.com/kcl-lang/kcl/blob/main/inlay_hints.rs), display the concrete types of expressions that lack explicit type annotations directly in your editor buffer. This visual feedback makes it immediately apparent where implicit type conversions occur or where a variable's inferred type differs from your expectations, helping you spot configuration errors before they cause runtime failures.