Diagnostic Codes
Every code range, the codes you will actually hit, and what each one means.
Every diagnostic Psy emits has a stable code, a severity, a message, a file, line, column and range, and related locations where they help.
spec/syntax/values.psy:26:9 error PSY4001: `ScalarValues.syntax` must be `string`
but resolved to an object.
spec/framework.psy:21:5: `syntax` is declared hereDiagnostics are sorted by file, then source position, then code, so output is stable across runs and two runs can be diffed.
Severities are error, warning and info. Errors always fail the command.
Whether warnings fail is the diagnostics policy in
psy.config.ts.
Ranges
| Range | Area |
|---|---|
PSY1xxx | lexical |
PSY2xxx | syntactic |
PSY3xxx | semantic |
PSY4xxx | types and composition |
PSY5xxx | lint |
PSY6xxx | frameworks |
PSY9xxx | tooling |
Codes are stable across versions.
Lexical — PSY1xxx
| Code | Meaning |
|---|---|
PSY1001 | tabs used for indentation |
PSY1003 | unindent matches no enclosing level |
PSY1005 | unterminated interpolation |
Syntactic — PSY2xxx
| Code | Meaning |
|---|---|
PSY2001 | interpolation contents are not a dotted identifier path |
PSY2004 | invalid declaration keyword |
PSY2005 | as on a concrete spec |
PSY2006 | abstract spec exported without a keyword |
PSY2007 | a block mixes object, list or text content |
PSY2011 | nested spec declaration |
PSY2015 | composition operator used inline |
PSY2016 | malformed module specifier |
PSY2017 | default import |
PSY2018 | namespace import |
Semantic — PSY3xxx
| Code | Meaning |
|---|---|
PSY3001 | duplicate symbol in the module namespace |
PSY3002 | unresolved reference |
PSY3003 | module not found |
PSY3005 | circular module dependency |
PSY3006 | circular inheritance |
PSY3007 | circular reference |
PSY3008 | unknown declaration keyword |
PSY3009 | duplicate declaration keyword |
PSY3011 | extending something that is not a spec |
PSY3012 | super with no parents |
PSY3013 | no parent defines the property |
PSY3014 | reading a key that does not exist |
PSY3015 | abstract property not implemented |
PSY3016 | abstract property on a concrete spec |
PSY3017 | unknown self field, or self outside a spec |
PSY3019 | duplicate property |
PSY3021 | declaration keyword shadows a reserved word |
Types and composition — PSY4xxx
| Code | Meaning |
|---|---|
PSY4001 | type mismatch |
PSY4002 | value kind is not composable |
PSY4003 | incompatible composition |
PSY4004 | ++ applied to a non-list |
PSY4005 | unknown named type |
PSY4006 | property access on a non-object |
PSY4007 | non-scalar interpolation |
Lint — PSY5xxx
| Code | Rule | Detects |
|---|---|---|
PSY5001 | noUnusedImports | a name is imported but never used |
PSY5002 | noUnusedSpecs | a spec is neither exported nor referenced |
PSY5003 | noUnusedConsts | a constant is neither exported nor referenced |
PSY5004 | specNaming | a spec or constant name is not PascalCase |
PSY5005 | propertyNaming | a property name is not camelCase |
PSY5006 | keywordNaming | a declaration keyword is not lowercase kebab-case |
PSY5007 | noUnusedUse | a use activates keywords the module never writes |
keywordNaming overlaps with PSY2004 — an invalid keyword is already rejected
by the parser, so the rule mainly guards tooling that lints partially valid input.
Frameworks — PSY6xxx
| Code | Meaning |
|---|---|
PSY6001 | the default code for a framework-reported finding |
Frameworks report against the declaration that caused the problem. Morphic's rules are listed in What Comes Out.
Tooling — PSY9xxx
| Code | Meaning |
|---|---|
PSY9001 | the config file could not be loaded |
PSY9003 | a file is not canonically formatted (psy format --check) |
PSY9004 | a generated artifact is out of date (psy build --check) |
PSY9005 | unknown or unselected psy init template |
PSY9006 | psy init target directory is not empty |
Diagnostics are specified in Psy
Each important failure mode has a diagnostic-rule in the self-specification:
export diagnostic-rule CircularInheritance:
description:
Inheritance cycles are rejected.
code: PSY3006
condition:
A spec appears in its own transitive inheritance chain.
diagnostic:
Circular inheritance is not allowed.{
"CircularInheritance": {
"code": "PSY3006",
"description": "Inheritance cycles are rejected.",
"condition": "A spec appears in its own transitive inheritance chain.",
"diagnostic": "Circular inheritance is not allowed."
}
}The test suite asserts that every diagnostic code an invalid fixture expects is described by one of these rules — so a code cannot exist without a written reason for existing. See Psy Describes Psy.