2.6 Diagnostics
Note
This specification may be incomplete at this time.
🎯 Every problem the RDCore platform finds in a workspace — a syntax error, a static or runtime compilation error, an analyzer finding — surfaces to the editor as an LSP diagnostic carrying a stable code, a help URL for that code, and, for error diagnostics, structured detail.
Diagnostic codes are grouped into four families by the layer that raises them:
| Family | Prefix | Raised by | Section |
|---|---|---|---|
| Syntax errors | VBC |
the parser (concrete syntax tree) | §2.6.1 |
| Semantic compilation errors | VBC |
the static semantics layer (abstract syntax tree) | §2.6.2 |
| Runtime errors | VBR / VBA |
the runtime semantics layer / workspace Err.Raise |
§2.6.3 |
| Rubberduck Core diagnostics | RDC |
the RDCore.Diagnostics analyzers |
§2.6.4 |
The numeric portion is a five-digit zero-padded code (VBC00001, VBR00009, RDC01001). Each code
is documented on its own page under Diagnostics
(https://rubberduck-vba.github.io/RDCore/diagnostics/<code>.html), and every emitted diagnostic
points there through the LSP codeDescription field — the client opens that URL when the reader
follows a diagnostic's "learn more".
A code's page is published the moment the platform can emit that code — the documentation grows at the same rate as the diagnostics. A published code is not renumbered and not retired so that older builds' diagnostic links keep resolving; the page's prose may evolve as the ideal set of codes is narrowed down.
Pipeline
The language server does not compute diagnostics itself. A diagnostics provider is a platform
extension whose manifest advertises the DiagnoseDocument capability
([assembly: ProvidesCorePlatformClientCapability<DiagnoseDocument>], recorded by
rdc.exe describe-ext in the extension's
extension.manifest.json). The set of registered capabilities —
not a hard-coded list — determines which extensions the language server asks. RDCore.Diagnostics
is the core-bundled provider, always brought up during platform assembly; other extensions
(dimensional analysis, and so on) register alongside it. With no provider registered, a workspace
simply has no diagnostics.
Diagnostics use the LSP 3.17 pull model (textDocument/diagnostic). When the editor asks for a
document, the language server, as orchestrator:
- resolves the workspace document and its current version;
- parses it (the authoritative parse);
- fans the parsed
ModuleParseResultout to every registered provider over the internalrdcore/diagnostics/documentrequest — the language server owns the document and parser state and pushes them down, so a provider needs no parser or file-system access of its own; - aggregates the LSP
Diagnostics the providers return (each provider projects its own findings throughICoreDiagnosticsFactory), collapsing exact duplicates, and answers the pull.
rdcore/diagnostics/document carries the parse result as a
PlatformJson string because the syntax tree is polymorphic; it
is the seam a future SemanticContext (resolver output) is added to, so the semantic and runtime
passes receive the same envelope. The editor edge stays plain LSP throughout — only the
language-server-to-provider hop is an RDCore request.
The report's resultId tracks the document's in-memory version. A previousResultId that still
matches answers a RelatedUnchangedDocumentDiagnosticReport and computes nothing. Results are also
staleness-gated: the version is captured before the fan-out and re-checked after; a report that
raced a later edit is dropped rather than returned, and the resultId advances to the current
version.
Note
Document versioning is inert until textDocument/didChange is handled — today the version only
moves on workspace reload or rename. Proactive push (textDocument/publishDiagnostics) and
workspace-wide diagnostics (workspace/diagnostic) are forthcoming; the pull pipeline is the seam
they hang off. On start-up the language server pulls diagnostics for every loaded document once, to
exercise the fan-out without an editor attached.
2.6.1 Syntax Errors
A syntax error is raised while the parser traverses the concrete syntax tree (CST) — a token the grammar cannot place. It is the inaugural diagnostic the platform emits.
| Code family | VBC — VBC00001–VBC00999 |
| Source metadata | VBSyntaxErrorInfo (ErrorId is a VBCompileErrorId) |
| Severity | Error |
| Detail | the faulted token and its expected role, on Diagnostic.data |
MS-VBAL does not distinguish a compile-time error raised in CST semantics from one raised in AST
semantics; RDCore splits them by numeric range only. A #If that splits a statement is unparseable
by the grammar and reports located VBC diagnostics a client can anchor a squiggle on.
The parser deliberately narrows its output over time: VBC00001 is the general fallback, and
recurring shapes are promoted to a dedicated code in the VBC00042–VBC00999 range. Published so
far:
| Code | Condition |
|---|---|
VBC00001 |
a token the grammar cannot place |
VBC00042 |
a numeric literal outside the range of its type |
2.6.2 Semantic Compilation Errors
A semantic compilation error is raised by the static semantics layer while walking the abstract syntax tree (AST) with symbol information — a duplicate declaration, an undefined name, a type mismatch in a constant expression.
| Code family | VBC — VBC09300–VBC09999 |
| Source metadata | VBCompileErrorInfo |
| Severity | Error |
| Detail | the offending symbol / expression, on Diagnostic.data |
Emitted once the resolver and static semantic pass are online; the provider projects them through the
same ICoreDiagnosticsFactory as syntax errors.
2.6.3 Runtime Errors
A runtime error is raised by the runtime semantics layer and left unhandled by workspace code — a subscript out of range, a type-mismatch coercion, division by zero.
| Code family | VBR — the numeric portion matches the corresponding MS-VBA run-time error code |
| Source metadata | VBRuntimeErrorInfo |
| Severity | Error |
An application error is a custom run-time error explicitly raised from workspace source code with
Error or Err.Raise. MS-VBAL does not distinguish it from a semantic run-time error.
| Code family | VBA — pseudo-code; the numeric portion matches the application-supplied error code |
| Source metadata | VBApplicationErrorInfo |
| Severity | Error |
2.6.4 Rubberduck Core Diagnostics
Rubberduck Core diagnostics are the analyzer findings issued by the RDCore.Diagnostics
analyzers — implicit declarations, obsolete syntax, misleading constructs, and every inspection the
legacy Rubberduck add-in shipped, and then some.
| Code family | RDC — RDCoreDiagnosticId; the enum value is the code |
| Severity | spans Hint through Error, per finding |
Unlike the VBC/VBR/VBA families, which describe conditions the language core defines, RDC
diagnostics are opinions of the analyzer. Diagnostics contributed by other extensions must use
their own prefix, distinct from RDC, so codes stay unique and traceable to their source.
⏮️ RD-VBAL §2.5 Runtime Values | ⏭️ RD-VBAL §3.0 Syntax Tree