#Diagnostics
#Shape
- A diagnostic has a code, severity, optional source span, and typed arguments.
- Source spans identify a file name, start position, and end position.
- Positions are zero-based and include byte offset, line, and column.
#Message Localization
- Every user-visible diagnostic message must be defined in a locale catalog.
- Implementation code must not embed user-visible diagnostic message strings.
- Diagnostic codes, constants, severities, and argument schemas are defined in a diagnostic registry.
- Locale catalogs contain only diagnostic code and localized message template columns.
- The English locale is required during development.
- Other locales, including Japanese, must be addable without changing diagnostic call sites.
- Diagnostics store code, severity, span, and typed arguments.
- Diagnostic reporters render localized messages from the locale catalog.
- Diagnostics that are not tied to source text may omit the source span.
- Catalog templates use
{name} placeholders for arguments.
- All placeholders used by a localized message must be declared by that diagnostic code's argument schema.
- All diagnostic codes must have an English message.
- Missing messages, unknown message codes, or mismatched placeholders are errors in generation or tests.
- Diagnostic code catalogs are stable user-visible contracts.
- Adding, removing, or renaming a diagnostic code is a user-visible behavior change.
- At this stage, diagnostic argument schemas only define string arguments.
#Reporters
- Text reporters write one localized diagnostic message per line.
- JSON reporters write an object with a
diagnostics array.
- Each JSON diagnostic entry contains
code, severity, message, optional span, and optional args.
- When there are no diagnostics, JSON reporters write an empty
diagnostics array.
#Severities
error: the source cannot be accepted for the requested operation.
warning: the source can be accepted, but the behavior should be reviewed.
info: informational output.
hint: editor-oriented guidance.
#Master Validation Diagnostics
The master validation feature registers the following diagnostic codes.
#Validator Evaluation
| Code | Severity | Meaning | Arguments |
|---|
masterbelt.validation.assert_failed | configured (default error) | An assert condition evaluated false. The span is the condition expression. | master, validator, scope (each/all), record, expr |
masterbelt.validation.evaluation_failed | error | A validation rule body raised a hard evaluation error. | master, validator, scope, detail |
masterbelt.validation.assert_failed is emitted at the severity resolved from project configuration: the default is error, and a (master, validator) override to warning is reflected in the emitted diagnostic. The master argument is the entrypoint-visible master path; the record argument is the failing record's primary-key description for an each failure and <table> for an all failure; expr is the condition's source text.
#Validator Configuration
| Code | Severity | Meaning | Arguments |
|---|
masterbelt.validation.config_unknown_master | error | A validators config key names a master that does not exist. | master |
masterbelt.validation.config_unknown_validator | error | A validators config key names a validator that does not exist on a known master. | master, validator |
masterbelt.validation.config_invalid_severity | error | A validators severity is not error or warning. | master, validator, severity |
masterbelt.validation.ambiguous_master | error | A master is re-exported from the entry module under more than one name, so no config path identifies it unambiguously; its validators are skipped. | master, aliases |
A master that the entry module neither declares nor re-exports has no entrypoint-visible config path, so its validators are out of scope and run no diagnostics.
#Checker
| Code | Severity | Meaning | Arguments |
|---|
masterbelt.checker.validator_duplicate | error | A duplicate validator id within a master. | master, name |
masterbelt.checker.assert_outside_validation | error | assert used outside a validation block. | — |
masterbelt.checker.return_in_validation | error | return used inside a validation block. | — |
masterbelt.checker.assert_condition_non_bool | error | An assert condition is not bool. | actual |
#Parser
| Code | Severity | Meaning |
|---|
masterbelt.parser.assert_missing_condition | error | An assert statement has no condition expression. |
masterbelt.parser.master_validation_group_missing_scope | error | A validation group is missing its each / all scope. |
masterbelt.parser.master_validation_rule_missing_name | error | A validate rule is missing its identifier. |
masterbelt.parser.master_validation_rule_missing_body | error | A validate rule is missing its body block. |
masterbelt.parser.unexpected_master_validation_node | error | An unexpected node appeared inside a validation section. |
A duplicate validation section within a master reuses the existing masterbelt.parser.master_section_duplicate code.
#Scope Diagnostics
The master scope section and the SQLite indexed-scope inference contribute the following diagnostics.
#Parser
| Code | Severity | Meaning |
|---|
masterbelt.parser.master_scope_missing_name | error | A scope declaration has no name. |
masterbelt.parser.master_scope_missing_body | error | A scope declaration has no body. |
#Checker
| Code | Severity | Meaning | Arguments |
|---|
masterbelt.checker.duplicate_scope | error | A duplicate scope name within one master. | master, name |
masterbelt.checker.scope_name_conflict | error | A scope name collides with a relation method, nested master, static, function, or const. | master, name |
masterbelt.checker.scope_return_type_mismatch | error | A scope body returns something other than the declaring master's Relation<M>. | master, actual |
masterbelt.checker.scope_missing_return | error | A block-body scope has no return. | master, name |
masterbelt.checker.scope_forbidden_effect | error | A scope body or query callback inherits failable / cancellable / asyncable. | master, name, effect |
masterbelt.checker.cyclic_scope | error | A scope references itself directly or transitively. The span is the cycle-closing call's callee. | master, name |
masterbelt.checker.scope_unknown_field | error | A query callback references a field the record does not declare. | master, field |
Some scope misuse reuses existing diagnostics rather than a scope-specific code: declaring or assigning self is reported as masterbelt.parser.reserved_identifier because self is lexically reserved (see lexical.md); a scope call with the wrong argument count or types is reported through the general call diagnostics (masterbelt.checker.call_argument_count_mismatch, masterbelt.checker.call_argument_type_mismatch); and a scope call on a receiver that does not expose the scope is reported as masterbelt.checker.unknown_member.
#SQLite Index Inference
| Code | Severity | Meaning | Arguments |
|---|
masterbelt.scope.index_inference_failed | warning | An indexed scope could not be fully turned into a secondary index; any inferable part is still generated. | master, scope |
masterbelt.scope.index_generated | info | A secondary index was generated from an indexed scope. | master, scope, index |