Diagnostics [[lsp_diagnostics: Category]]Category
Document validation with errors and warnings displayed in the editor. Groups the diagnostics feature and its rules.
Diagnostics [[diagnostics: LSPFeature]]LSPFeatureCompletion LSPFeature 80%Hover LSPFeature 80%Code Action LSPFeature 78%
Red and yellow underlines in the editor for errors and warnings.
- lsp_method: textDocument/publishDiagnostics
- status: implemented
- depends: Rust Parser
Description [[description: text]]textWorkspace In Wrong File ValidationError 91%Validate a Document HowTo 83%Workspace Workspace 80%
Update triggers:
textDocument/didOpen— when a file is openedtextDocument/didChange— on changes (with debounce)textDocument/didSave— on saveworkspace/didChangeWatchedFiles— when other files change
Errors (red):
- Broken Link (QMDC001) — reference to a non-existent object
- Duplicate ID (QMDC003) — duplicate IDs
- Workspace In Wrong File (QMDC004) — workspace in wrong file
- Ambiguous Field Reference (QMDC009) — reference is ambiguous between a hierarchical object
__idand a field on the prefix object
Planned errors (not yet implemented):
- Ambiguous Reference (QMDC002) — ambiguous reference
- Invalid Reference Syntax (QMDC006) — invalid reference syntax
Planned warnings (not yet implemented, requires schema registry):
- Unknown Kind (QMDC005) — unknown Kind
- Missing Required Field (QMDC007) — missing required field
- Invalid Field Type (QMDC008) — incorrect field type
Related information: For some errors, related information is shown:
- Duplicate ID → first definition line number in message text
Example:
- user: [[#alice]]
^^^^^^^^^^^ ← Error (QMDC001): Object 'alice' not found
## Users [[users]]
...
## Users [[users]]
^^^^^^^^^ ← Error (QMDC003): Duplicate ID 'users'
(first defined on line 5)
Broken Link [[rule_broken_link: DiagnosticRule]]DiagnosticRuleDiagnostics McpResource 83%Common Errors NarrativeDoc 80%Validate a Document HowTo 79%
Reference to a non-existent object.
- code: QMDC001
- severity: error
- validates: Broken Link
Description [[description: text]]text
Pattern: [[#id]] where id does not exist in the workspace (neither as __id nor as __local_id).
Message:
Object '{id}' not found
Range: the entire reference [[#id]] is underlined in red.
Related information:
When a broken link's id matches a __local_id in another namespace, the diagnostic includes a hint suggesting the full qualified reference. For example, if [[#config]] is broken but storage:parent.config has __local_id: "config", the hint suggests using [[#storage:parent.config]].
Example:
- user: [[#alice]]
^^^^^^^^^^^ ← Error: Object 'alice' not found
- config: [[#config]]
^^^^^^^^^^^ ← Error: Object 'config' not found
Hint: Did you mean '[[#storage:app.config]]'?
Ambiguous Reference [[rule_ambiguous_ref: DiagnosticRule]]DiagnosticRuleAmbiguous Field Reference ValidationError 79%Validation Errors SyntaxConcept 74%Diagnostics McpResource 73%
Ambiguous reference — ID exists in multiple namespaces, with different Kinds, or matches multiple __local_id values.
- code: QMDC002
- severity: error
- status: planned
- validates: Ambiguous Reference
Description [[description: text]]text
Pattern: [[#id]] where id exists in multiple places:
- Different namespaces:
storage:usersandauth:users - Different Kinds:
Table:usersandView:users - Multiple
__local_idmatches: several child objects with the same local name (e.g.,parent1.configandparent2.configboth have__local_id: "config")
Message:
Ambiguous reference '{id}', found in: {locations}
Related information: shows a list of all candidates with their locations.
Resolution: add a qualifier:
[[#namespace:id]]— specify namespace[[#Kind:id]]— specify Kind[[#namespace:Kind:id]]— specify both[[#parent.child]]— use full hierarchical ID (for__local_idambiguity)
Example:
- table: [[#users]]
^^^^^^^^^^^ ← Error: Ambiguous reference 'users'
Found in: storage:users, auth:users
- cfg: [[#config]]
^^^^^^^^^^^ ← Error: Ambiguous reference 'config'
Found in: app.config, server.config
Duplicate ID [[rule_duplicate_id: DiagnosticRule]]DiagnosticRuleAmbiguous Reference ValidationError 74%Invalid ID Character ValidationError 72%Multiple Definitions In Heading ValidationError 71%
Two objects with the same FULL hierarchical __id in one namespace. Parent-scoped
children with the same local id do not collide.
- code: QMDC003
- severity: error
- validates: Duplicate ID
Description [[description: text]]text
Pattern: two headings resolve to the same full hierarchical __id in one
namespace. Kind is not part of duplicate identity.
Message:
Duplicate ID '{id}' (first defined on line {line})
Range: the ID definition of the second object is underlined in red.
First definition: its line number is included in the diagnostic message.
Example:
## Users [[users]]
...
## Users [[users]]
^^^^^^^^^ ← Error: Duplicate ID 'users' (first defined on line 5)
Unknown Kind [[rule_unknown_kind: DiagnosticRule]]DiagnosticRuleExplicit System Type ValidationError 72%Kind in Heading CompletionContext 69%Kind in Reference CompletionContext 69%
Kind not found in the workspace schemas.
- code: QMDC005
- severity: warning
- status: planned
Description [[description: text]]text
Pattern: [[id: UnknownKind]] where UnknownKind is not defined in the workspace.
Message:
Unknown Kind '{kind}'
Range: the Kind in the heading is underlined in yellow.
This is a warning, not an error — QMD.md allows arbitrary Kinds. But if the workspace has a schema registry, unknown Kinds may be typos.
Example:
## My Service [[my_service: Servise]]
^^^^^^^ ← Warning: Unknown Kind 'Servise'
Did you mean 'Service'?
Invalid Reference Syntax [[rule_invalid_ref: DiagnosticRule]]DiagnosticRuleAmbiguous Reference ValidationError 81%Diagnostics McpResource 77%Reference Reference 76%
Invalid reference syntax.
- code: QMDC006
- severity: error
- status: planned
Description [[description: text]]text
Patterns:
[[#]]— empty reference[[#:]]— colon only[[#::id]]— double colon[[# id]]— space after hash[[#id ]]— space before closing bracket
Message:
Invalid reference syntax
Range: the entire reference is underlined in red.
Example:
- ref: [[#]]
^^^^^ ← Error: Invalid reference syntax
- ref: [[# users]]
^^^^^^^^^^^ ← Error: Invalid reference syntax (space after #)
Missing Required Field [[rule_missing_field: DiagnosticRule]]DiagnosticRuleDangling Field ValidationError 83%Validation Errors SyntaxConcept 72%Ambiguous Field Reference ValidationError 72%
A required field is missing for the given Kind (if a schema exists).
- code: QMDC007
- severity: warning
- status: planned
Description [[description: text]]text
Pattern: an object with a Kind that has a defined schema, but a required field is missing.
Message:
Missing required field '{field}' for Kind '{kind}'
Range: the object heading is underlined in yellow.
Requires schema registry. If no schema exists, this rule does not apply.
Example:
## My Table [[my_table: Table]]
^^^^^^^^^^^^^^^^^^^^^^^^^^ ← Warning: Missing required field 'columns' for Kind 'Table'
- name: my_table
Invalid Field Type [[rule_invalid_field_type: DiagnosticRule]]DiagnosticRuleDangling Field ValidationError 77%Mixed Field Keys ValidationError 77%Explicit System Type ValidationError 75%
The field value type does not match the schema.
- code: QMDC008
- severity: warning
- status: planned
Description [[description: text]]text
Pattern: a field has a value of the wrong type according to the schema.
Message:
Invalid type for field '{field}': expected {expected}, got {actual}
Range: the field value is underlined in yellow.
Requires schema registry.
Example:
## My Table [[my_table: Table]]
- name: my_table
- row_count: "100"
^^^^^ ← Warning: Invalid type for field 'row_count': expected number, got string
Workspace In Wrong File [[rule_workspace_wrong_file: DiagnosticRule]]DiagnosticRuleWorkspace In Wrong File ValidationError 89%Validation Errors SyntaxConcept 82%Validate References McpTool 75%
Workspace declaration in a file other than readme.qmd.md.
- code: QMDC004
- severity: error
Description [[description: text]]text
Pattern: a __Workspace object is defined in a file that is not readme.qmd.md.
Message:
Workspace '{id}' must be defined in readme.qmd.md, not here
Range: the heading of the workspace object is underlined in red.
Example:
# My Project [[myproject: __Workspace]]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ← Error: Workspace 'myproject' must be defined in readme.qmd.md
Ambiguous Field Reference [[rule_ambiguous_field_ref: DiagnosticRule]]DiagnosticRule
A dotted reference resolves both as a hierarchical object __id and as a field on the prefix object.
- code: QMDC009
- severity: error
- validates: Ambiguous Field Reference
Description [[description: text]]text
Pattern: [[#a.b]] where an object with __id: "a.b" exists AND object a has a field b whose value is not the parser-generated child link [[#a.b]].
Message:
Reference '{target}' cannot be unequivocally resolved to an object or a field: object with __id '{a.b}'; field '{b}' on object '{a}' (value: {...})
Range: the entire reference is underlined in red.
Example:
## Team [[team]]
- score: 100
## Score Details [[team.score]]
- ref: [[#team.score]]
^^^^^^^^^^^^^^^ ← Error: ambiguous between object 'team.score' and field 'score' on 'team'
Surface Coverage [[surface_coverage: Section]]Section
Which surface emits which diagnostic. CLI = qmdc workspace validate; LSP = editor
diagnostics; MCP = qmdc_validate_references + qmdc://diagnostics. Reference
diagnostics for the CLI, LSP, and MCP all come from one shared engine
(core::reference_scan::reference_scan); duplicate detection is namespace-scoped per
QMD-67 (core::ops::validate::collect_duplicate_issues), shared by all three surfaces.
Matrix [[surface_matrix: text]]text
| Diagnostic | code | CLI | LSP | MCP |
|---|---|---|---|---|
| broken_link | QMDC001 | yes | yes | yes |
| ambiguous_reference | QMDC002 | yes | yes | yes |
| duplicate_id (same-file) | QMDC003 | yes | yes | yes |
| duplicate_id (cross-file / namespace-scoped) | QMDC003 | yes | yes | yes |
| workspace_in_wrong_file | QMDC004 | yes | yes | yes |
| ambiguous_field_reference | QMDC009 | yes | yes | yes |
| broken_parent | broken_parent | yes | no | yes |
| nested_workspace | nested_workspace | yes | no | yes |
| parser structural (dangling_field, mixed_field_keys, multiple_definitions, structured_in_textblock, invalid_id_character, explicit_system_type, nested_subitems, ordered_list_in_array, invalid_map_entry, invalid_map_content) | (type) | yes | yes | yes |
Notes [[surface_notes: text]]text
- LSP same-file
duplicate_idcomes from a per-document scan (works with no workspace); cross-file/namespace-scopedduplicate_idcomes from the shared detector. The two do not double-report. broken_parentandnested_workspaceare workspace-level and are not surfaced by the single-document LSP path; they appear in CLI and MCP.- Single engine: broken_link / ambiguous_reference / ambiguous_field_reference are all
produced by one shared implementation,
core::reference_scan::reference_scan, used by the CLI, the LSP, and MCP — so the three surfaces cannot drift. The CLI and LSP pass file content so inline-code (double-backtick) references stay suppressed; MCP relies on the parser's single-backtick stripping (double-backtick suppression on the MCP path is a known minor gap with no test coverage).