How to Debug KCL Configuration Issues Leveraging LSP Tools
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 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, 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 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, 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 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 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 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, 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 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 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 suggests CodeAction objects based on patterns detected by the analyzer, such as adding missing imports or fixing common schema violations. Additionally, 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 and 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 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, 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 that rebuilds only the affected parts of the program. The 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 module routes incoming LSP JSON-RPC requests to the appropriate handler functions (hover, goto-def, etc.), while 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, the dispatch logic maps method names to handler modules, and 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:
// settings.json
{
"kcl.languageServer.path": "kcl-lsp",
"editor.codeActionsOnSave": {
"source.fixAll": true
}
}
This configuration ensures that diagnostic.rs runs on every change, and 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:
{
"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:
{
"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:
{
"method": "textDocument/definition",
"params": {
"textDocument": { "uri": "file:///project/app.k" },
"position": { "line": 24, "character": 10 }
}
}
The response from 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 where the symbol is declared.
Tracking Variable Usage with References
Find all usages of a potentially misconfigured variable:
{
"method": "textDocument/references",
"params": {
"textDocument": { "uri": "file:///project/app.k" },
"position": { "line": 8, "character": 3 },
"context": { "includeDeclaration": true }
}
}
This queries 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:
{
"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.rssurface compile-time errors immediately as you edit KCL files. - Hover inspection via
hover.rsreveals the exact type, value, and documentation for any symbol under your cursor. - Navigation features in
goto_def.rsandfind_refs.rsallow you to trace symbol origins and track value propagation through complex configurations. - Inlay hints from
inlay_hints.rsdisplay implicit types directly in the editor buffer, making type mismatches visually obvious. - Quick fixes in
quick_fix.rsprovide automated corrections for common configuration errors like missing imports. - Incremental compilation powered by Salsa in
compile.rsensures 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 virtual file system and triggers incremental compilation via compile.rs on every edit. The 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 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, 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →