Documentation
Diagnostic Codes
Reference for PLC diagnostics with minimal examples that trigger each code.
Diagnostic Codes
This page lists the diagnostic codes emitted by the language server and plccheck. The examples are intentionally minimal. Most SCL examples are fragments that should be placed inside a normal block body or declaration section, and project-wide diagnostics may require the companion file or PLC-root setup described in the example.
SCL Lexer And Parser
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCL_LEX_UNTERMINATED_STRING | A single-quoted string literal is not closed. | #Name := 'open; |
SCL_LEX_UNEXPECTED_HASH | A # local marker is not followed by an identifier. | # := TRUE; |
SCL_LEX_UNEXPECTED_TOKEN | The lexer found a character that is not valid at that position. | #Value := @; |
SCL_LEX_UNTERMINATED_ATTRIBUTE_BLOCK | A Siemens attribute block starts with { and never closes. | { S7_Optimized_Access := 'TRUE' |
SCL_LEX_UNTERMINATED_QUOTED_IDENTIFIER | A double-quoted identifier is not closed. | "OpenName := 1; |
SCL_PARSE_DECL_INIT_UNEXPECTED_TOKEN | A declaration initializer has mismatched delimiters. | VAR x : ARRAY[1..2] OF INT := [1, 2); END_VAR |
SCL_PARSE_EXPECTED_TOKEN | A required punctuation token is missing. | VAR x INT; END_VAR |
SCL_PARSE_EXPECTED_KEYWORD | A required keyword is missing. | FUNCTION_BLOCK FB VAR x : INT; END_VAR |
SCL_PARSE_EXPECTED_IDENTIFIER | A declaration or construct expected an identifier. | FUNCTION_BLOCK ; END_FUNCTION_BLOCK |
SCL_PARSE_UNEXPECTED_TOKEN | A token appears where the parser recovery set does not allow it. | FUNCTION_BLOCK FB BEGIN ; END_FUNCTION_BLOCK |
SCL_EXPR_TRAILING_TOKEN | Expression parsing finished but extra tokens remained. | #Value := 1 2; |
SCL Type Definitions
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCL_TYPEDEF_EXPECTED_DECL_SEMICOLON | A type declaration is not terminated with ;. | TYPE T : INT T2 : INT; END_TYPE |
SCL_TYPEDEF_UNTERMINATED_TYPE_SECTION | A TYPE section is missing END_TYPE. | TYPE T : INT; |
SCL_TYPEDEF_EXPECTED_TYPE_REF | A type alias, field, or array element is missing its referenced type. | TYPE T : ; END_TYPE |
SCL_TYPEDEF_EXPECTED_FIELD_COLON | A STRUCT field is missing : after its name. | TYPE T : STRUCT Field INT; END_STRUCT; END_TYPE |
SCL_TYPEDEF_EXPECTED_FIELD_SEMICOLON | A STRUCT field declaration is missing ;. | TYPE T : STRUCT Field : INT Next : INT; END_STRUCT; END_TYPE |
SCL_TYPEDEF_UNTERMINATED_STRUCT | A STRUCT declaration is missing END_STRUCT. | TYPE T : STRUCT Field : INT; END_TYPE |
SCL_TYPEDEF_ARRAY_BOUNDS_UNTERMINATED | An ARRAY[ bounds list is missing ]. | TYPE T : ARRAY[1..10 OF INT; END_TYPE |
SCL_TYPEDEF_ARRAY_EXPECT_OF | An array type is missing OF. | TYPE T : ARRAY[1..10] INT; END_TYPE |
SCL Semantic Checks
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCL_SEM_AT_UNDECLARED_TARGET | A symbolic AT target does not exist. | VAR_TEMP Overlay AT Missing.Target : BOOL; END_VAR |
SCL_SEM_AT_INVALID_TARGET_PATH | A symbolic AT target exists but the member path is invalid. | VAR_TEMP Base : STRUCT Ok : BOOL; END_STRUCT; Overlay AT Base.Missing : BOOL; END_VAR |
SCL_SEM_ASSIGN_UNDECLARED_TARGET | An assignment writes to an undeclared target. | Missing := 1; |
SCL_SEM_INVALID_DESIGNATOR_PATH | A designator path references a member or index that cannot exist. | #StructValue.Missing := 1; |
SCL_SEM_REFERENCE_UNDECLARED_LOCAL | An expression references an undeclared local symbol. | #Out := #Missing; |
SCL_SEM_ARRAY_INDEX_COUNT | An array is indexed with the wrong number of dimensions. | #Arr[1, 2] := 0; |
SCL_SEM_ARRAY_INDEX_TYPE | An array index is not integer-compatible. | #Arr[TRUE] := 0; |
SCL_SEM_ARRAY_INDEX_BOUNDS | A constant array index is outside the declared bounds. | #Arr[99] := 0; |
SCL_SEM_ASSIGN_PRECISION_LOSS | An assignment is allowed but may lose sign or precision. | #SmallInt := #RealValue; |
SCL_SEM_ASSIGN_TYPE | An assignment is not type-compatible. | #RealValue := T#1s; |
SCL Call-Site Checks
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCL_CALL_UNKNOWN_PIN | A named call argument does not match a pin on the target FB or FC. | #Motor(NotAPin := TRUE); |
SCL_CALL_PIN_DIR_MISMATCH | A named call argument uses := or => against the wrong pin direction. | #Motor(Done := TRUE); |
SCL_CALL_PIN_TYPE | A named call argument has a type that cannot be assigned to or from the pin. | #Motor(Start := 1.5); |
SCL_DUPLICATE_INSTANCE_CALL | The same stateful FB instance is called more than once in one block. | #Timer(IN := TRUE); #Timer(IN := FALSE); |
PLC Tag Tables
| Code | Meaning | Minimal trigger example |
|---|---|---|
TAGTABLE_DUPLICATE_TAG_NAME | Two XML tag-table rows use the same tag name. | <Member Name="Start" /><Member Name="Start" /> |
TAGTABLE_TYPE_UNDEFINED | A tag-table row references a datatype not known in the PLC scope. | <Member Name="Bad" Datatype="MissingType" /> |
TAGTABLE_GLOBAL_NAME_CONFLICT | A tag name conflicts with another global PLC symbol. | Tag XML defines Motor_FB while an SCL file also declares FUNCTION_BLOCK Motor_FB. |
Project Library Resolution
| Code | Meaning | Minimal trigger example |
|---|---|---|
PLCLIB_LINK_PARSE | A .liblink placeholder cannot be parsed. | Program blocks/Library/Foo.liblink contains malformed metadata. |
PLCLIB_MISSING_TYPES_ROOT | A .plc.json library path points to a missing or non-directory types root. | .plc.json contains "libraries": ["../missing-types"]. |
PLCLIB_TYPE_GUID_NOT_FOUND | A .liblink references a type GUID that no discovered .libinfo provides. | A copied .liblink points to a library version that is not present under the configured Types root. |
PLCLIB_VERSION_GUID_AMBIGUOUS | The type GUID exists, but the requested version cannot be selected unambiguously. | Two .libinfo files share the same type GUID but do not match the .liblink version GUID. |
PLCLIB_METADATA_PARSE | A .libinfo or .libint sidecar cannot be parsed. | Types/Library/Foo.libinfo contains malformed metadata. |
PLCLIB_SOURCE_MISSING | Library metadata resolves, but the expected source file is missing. | Foo.libint lists Foo.scl, but Foo.scl is not present next to the sidecar files. |
S7RES And S7DCL Resource Links
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7RES_MISSING_DCL | A .s7res file has no same-basename .s7dcl sibling. | Motor.s7res exists, but Motor.s7dcl does not. |
S7RES_DCL_DUPLICATE_REFS | The sibling .s7dcl references the same resource ID more than once. | Motor.s7dcl contains two S7_NetworkTitle := "N01" assignments. |
S7RES_COUNT_MISMATCH | The number of .s7res entries does not match unique .s7dcl references. | .s7res has N01 and N02, but .s7dcl only references N01. |
S7RES_ID_NOT_REFERENCED | An .s7res ID is not referenced by the sibling .s7dcl. | .s7res contains - id: N99, but .s7dcl never references N99. |
S7RES_MISSING_ID | A .s7dcl resource ID reference has no .s7res entry. | .s7dcl references S7_NetworkTitle := "N02" while .s7res only defines N01. |
S7DCL_MISSING_ID | A .s7dcl resource ID reference is missing from an existing sibling .s7res. | Motor.s7dcl references S7_NetworkComment := "C01" while Motor.s7res lacks C01. |
S7RES_EMPTY_ID | A MultiLingualTexts entry has an empty id. | - id: |
S7RES_BAD_ID | A resource ID is suspicious and not a simple alphanumeric identifier. | - id: N-01 |
S7RES_MISSING_HEADER | A .s7res file lacks the expected MultiLingualTexts: header. | .s7res starts directly with - id: N01. |
S7RES_EMPTY | A .s7res file has the header but no entries. | MultiLingualTexts: with no - id: rows. |
S7DCL Embedded SCL Networks
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_SCL_META_UNTERMINATED | Metadata before an SCL NETWORK has an unterminated {...} block. | { S7_Language := "SCL" NETWORK |
S7DCL_SCL_UNTERMINATED_NETWORK | An SCL NETWORK is missing END_NETWORK. | { S7_Language := "SCL" } NETWORK #x := TRUE; |
S7DCL_SCL_NETWORK_PARSE | Fallback for an embedded SCL parser diagnostic that did not include a specific code. | { S7_Language := "SCL" } NETWORK malformed SCL END_NETWORK |
S7DCL_SCL_NETWORK_<SCL code> | Embedded SCL lexer/parser diagnostics are downgraded to warnings and prefixed with S7DCL_SCL_NETWORK_. | Missing ; inside an SCL NETWORK can produce S7DCL_SCL_NETWORK_SCL_PARSE_EXPECTED_TOKEN. |
S7DCL FBD Network Syntax
Examples in this section assume an .s7dcl FBD network body, for example { S7_Language := "FBD" } NETWORK ... END_NETWORK.
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_FBD_META_UNTERMINATED | Metadata before or inside an FBD network has an unterminated {...} block. | { S7_Language := "FBD" NETWORK |
S7DCL_FBD_EXPECT_NETWORK | The FBD parser was asked to parse a section that does not start with NETWORK. | FBD metadata is followed by RUNG TRUE instead of NETWORK. |
S7DCL_FBD_UNTERMINATED_NETWORK | An FBD NETWORK is missing END_NETWORK. | NETWORK RUNG TRUE END_RUNG |
S7DCL_FBD_DUP_WIRE_PRODUCER | Two rungs produce the same wire. | END_RUNG wire#w1 appears on two rungs. |
S7DCL_FBD_UNEXPECTED | The FBD network contains a token other than RUNG or END_NETWORK. | NETWORK BOX END_NETWORK |
S7DCL_FBD_EXPECT_RUNG | The FBD rung parser was asked to parse a section that does not start with RUNG. | NETWORK A(in2 := #Start) END_NETWORK |
S7DCL_FBD_UNTERMINATED_RUNG | An FBD RUNG is missing END_RUNG. | NETWORK RUNG TRUE A(in2 := #Start) END_NETWORK |
S7DCL_FBD_EXPECT_LPAREN | An FBD element or pin list is missing (. | RUNG TRUE A in2 := #Start) END_RUNG |
S7DCL_FBD_UNTERMINATED_EXPR | An FBD element, coil, or pin expression is missing a closing delimiter. | RUNG TRUE Coil(#Out END_RUNG |
S7DCL_FBD_UNTERMINATED_PINLIST | A call or boolean operator pin list is not closed. | RUNG TRUE A(in2 := #Start END_RUNG |
S7DCL_FBD_EXPECT_PIN | A pin list entry does not start with a valid pin name. | RUNG TRUE A(1 := #Start) END_RUNG |
S7DCL_FBD_EXPECT_PIN_OP | A pin name is not followed by := or =>. | RUNG TRUE A(in2 #Start) END_RUNG |
S7DCL_FBD_BOOL_OP_INVALID_RUNG_HEADER | A boolean operator starts from a wire rung header. | RUNG wire#w1 A(in2 := #Start) END_RUNG wire#w2 |
S7DCL_FBD_BOOL_OP_MISSING_OUTPUT_CONNECTOR | A boolean operator is missing a valid left-side BOOL connector. | RUNG A(in2 := #Start) A(in2 := #Other) END_RUNG |
S7DCL_FBD_PIN_INLINE_BOOL_EXPR | A call pin contains inline AND or OR logic instead of FBD wires. | RUNG TRUE MyFB(in1 := #A AND #B) END_RUNG |
S7DCL_FBD_CALL_WIRE_PRODUCER_BEFORE_CONSUMER | A call consumes a wire whose producer rung appears before the consuming call. | First rung produces wire#w1; later call uses in1 := wire#w1. |
S7DCL_FBD_WIRE_NO_PRODUCER | A wire is consumed but no rung produces it. | RUNG TRUE MyFB(in1 := wire#w9) END_RUNG |
S7DCL FBD Semantic Checks
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_FBD_DUPLICATE_INSTANCE_CALL | The same stateful FB instance is called more than once in one block. | Two FBD elements call #Timer(...) in the same enclosing block. |
S7DCL_FBD_SEM_PIN_INPUT_TYPE | An input pin receives an incompatible expression type. | MyFB(IntPin := TRUE) where IntPin expects INT. |
S7DCL_FBD_SEM_PIN_OUTPUT_TYPE | An output pin writes to a target with an incompatible type. | MyFB(Done => #Counter) where Done is BOOL and #Counter is INT. |
S7DCL_FBD_SEM_UNRESOLVED_CALL | A dotted FBD call cannot be resolved enough for pin validation. | #Unknown.Nested(in1 := TRUE) |
S7DCL_FBD_SEM_RUNG_HEADER_TYPE | A rung header expression is not BOOL. | RUNG #Counter where #Counter is INT. |
S7DCL_FBD_SEM_INVALID_PATH | A local or quoted designator path has an invalid member or index. | Coil(#StructValue.Missing) |
S7DCL_FBD_SEM_UNDECLARED_LOCAL | An FBD expression references an undeclared local. | Coil(#MissingLocal) |
S7DCL_FBD_SEM_COIL_TARGET_TYPE | A coil or S_SR operand target is not BOOL. | Coil(#Counter) where #Counter is INT. |
S7DCL_FBD_SEM_BOOL_OP_ARG_TYPE | A boolean operator has a bad input pin name or non-BOOL input type. | A(in1 := #Start) or A(in2 := #Counter) |
S7DCL_FBD_SEM_BUILTIN_PIN_UNKNOWN | A builtin FBD call uses a pin name that the builtin does not define. | TON(BadPin := TRUE) |
S7DCL_FBD_SEM_BUILTIN_PIN_TYPE | A builtin FBD pin has the wrong direction or type. | TON(IN => #Start) or TON(PT := TRUE) |
S7DCL_FBD_SEM_BUILTIN_OPERAND_TARGET | S_SR uses an operand that is not an assignable designator. | S_SR(operand := TRUE) |
S7DCL FBD Transpile Diagnostics
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_FBD_TX_BLOCK_MAPPING | Transpiling one .s7dcl file produces more than one SCL block output name. | A single .s7dcl file declares two blocks. |
S7DCL_FBD_TX_EMPTY_NETWORK | An FBD network has no emitted statements. | NETWORK RUNG TRUE END_RUNG END_NETWORK |
S7DCL_FBD_TX_EXPR_FALLBACK | The FBD-to-SCL transpiler cannot parse an expression and emits a fallback. | MyFB(in1 := #A + ) |
S7DCL_FBD_TX_WIRE_CYCLE_FIXED_POINT | The FBD wire graph has a cycle and needs fixed-point lowering. | wire#w1 and wire#w2 feed each other through boolean rungs. |
S7DCL LAD Network Syntax
Examples in this section assume an .s7dcl LAD network body, for example { S7_Language := "LAD" } NETWORK ... END_NETWORK.
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_LAD_META_UNTERMINATED | Metadata before or inside a LAD network has an unterminated {...} block. | { S7_Language := "LAD" NETWORK |
S7DCL_LAD_EXPECT_NETWORK | The LAD parser was asked to parse a section that does not start with NETWORK. | LAD metadata is followed by RUNG instead of NETWORK. |
S7DCL_LAD_UNTERMINATED_NETWORK | A LAD NETWORK is missing END_NETWORK. | NETWORK RUNG TRUE END_RUNG |
S7DCL_LAD_UNEXPECTED | The LAD network contains a token other than RUNG or END_NETWORK. | NETWORK Contact(#Start) END_NETWORK |
S7DCL_LAD_EXPECT_RUNG | The LAD rung parser was asked to parse a section that does not start with RUNG. | NETWORK WIRE w1 END_NETWORK |
S7DCL_LAD_UNTERMINATED_RUNG | A LAD RUNG is missing END_RUNG. | NETWORK RUNG Contact(#Start) END_NETWORK |
S7DCL_LAD_EXPECT_WIRE_ID | A WIRE token is missing its wire ID. | RUNG WIRE END_RUNG |
S7DCL_LAD_EXPECT_LPAREN | A LAD element is missing ( after its name. | RUNG Contact #Start) END_RUNG |
S7DCL_LAD_UNTERMINATED_EXPR | A LAD element expression is missing ). | RUNG Contact(#Start END_RUNG |
S7DCL LAD Transpile Diagnostics
| Code | Meaning | Minimal trigger example |
|---|---|---|
S7DCL_LAD_TX_BLOCK_MAPPING | Transpiling one .s7dcl file produces more than one SCL block output name. | A single .s7dcl file declares two blocks. |
S7DCL_LAD_TX_EMPTY_NETWORK | A LAD network has no emitted statements. | NETWORK RUNG TRUE END_RUNG END_NETWORK |
S7DCL_LAD_TX_EXPR_FALLBACK | The LAD-to-SCL transpiler cannot parse an expression and emits a fallback. | Contact(#A + ) |
S7DCL_LAD_TX_WIRE_CYCLE_FIXED_POINT | The LAD wire graph has a cycle and needs fixed-point lowering. | Two LAD wire paths feed each other. |
SCL Test Parser
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCLTEST_PARSE_EXPECT_TEST_CASE | The parser expected a TEST_CASE declaration. | SET UUT.Start := TRUE; |
SCLTEST_PARSE_DUPLICATE_TARGET | A file declares TEST_TARGET more than once. | TEST_TARGET "FB1"; TEST_TARGET "FB2"; |
SCLTEST_PARSE_TARGET_ENTRY_CONFLICT | TEST_TARGET is combined with TEST_ENTRY. | TEST_TARGET "FB1"; TEST_ENTRY "OB1"; |
SCLTEST_PARSE_DUPLICATE_ENTRY | A file declares TEST_ENTRY more than once. | TEST_ENTRY "OB1"; TEST_ENTRY "OB2"; |
SCLTEST_PARSE_ENTRY_TARGET_CONFLICT | TEST_ENTRY is combined with TEST_TARGET. | TEST_ENTRY "OB1"; TEST_TARGET "FB1"; |
SCLTEST_PARSE_TARGET_EXPECT_SYMBOL | TEST_TARGET is missing its target symbol. | TEST_TARGET ; |
SCLTEST_PARSE_ENTRY_EXPECT_SYMBOL | TEST_ENTRY is missing its entry symbol. | TEST_ENTRY ; |
SCLTEST_PARSE_TARGET_EXPECT_SEMICOLON | TEST_TARGET is missing ;. | TEST_TARGET "FB1" |
SCLTEST_PARSE_ENTRY_EXPECT_SEMICOLON | TEST_ENTRY is missing ;. | TEST_ENTRY "OB1" |
SCLTEST_PARSE_TARGET_AFTER_CASE | TEST_TARGET appears after a test case has started. | TEST_CASE "A" END_TEST_CASE TEST_TARGET "FB1"; |
SCLTEST_PARSE_ENTRY_AFTER_CASE | TEST_ENTRY appears after a test case has started. | TEST_CASE "A" END_TEST_CASE TEST_ENTRY "OB1"; |
SCLTEST_PARSE_EXPECT_END_TEST_CASE | A test case is missing END_TEST_CASE. | TEST_CASE "A" SET UUT.Start := TRUE; |
SCLTEST_PARSE_EXPECT_CASE_NAME | TEST_CASE is missing its name. | TEST_CASE SET UUT.Start := TRUE; END_TEST_CASE |
SCLTEST_PARSE_UNKNOWN_STEP | A test case contains an unknown step keyword. | TEST_CASE "A" POKE UUT.Start := TRUE; END_TEST_CASE |
SCLTEST_PARSE_SET_EXPECT_TARGET | SET is missing the target expression. | TEST_CASE "A" SET := TRUE; END_TEST_CASE |
SCLTEST_PARSE_SET_EXPECT_ASSIGN | SET is missing :=. | TEST_CASE "A" SET UUT.Start TRUE; END_TEST_CASE |
SCLTEST_PARSE_SET_EXPECT_VALUE | SET is missing the value expression. | TEST_CASE "A" SET UUT.Start := ; END_TEST_CASE |
SCLTEST_PARSE_SET_EXPECT_SEMICOLON | SET is missing ;. | TEST_CASE "A" SET UUT.Start := TRUE END_TEST_CASE |
SCLTEST_PARSE_HOLD_EXPECT_TARGET | HOLD is missing the target expression. | TEST_CASE "A" HOLD := TRUE; END_TEST_CASE |
SCLTEST_PARSE_HOLD_EXPECT_ASSIGN | HOLD is missing :=. | TEST_CASE "A" HOLD UUT.Start TRUE; END_TEST_CASE |
SCLTEST_PARSE_HOLD_EXPECT_VALUE | HOLD is missing the value expression. | TEST_CASE "A" HOLD UUT.Start := ; END_TEST_CASE |
SCLTEST_PARSE_HOLD_EXPECT_SEMICOLON | HOLD is missing ;. | TEST_CASE "A" HOLD UUT.Start := TRUE END_TEST_CASE |
SCLTEST_PARSE_RELEASE_EXPECT_TARGET | RELEASE is missing the target expression. | TEST_CASE "A" RELEASE ; END_TEST_CASE |
SCLTEST_PARSE_RELEASE_EXPECT_SEMICOLON | RELEASE is missing ;. | TEST_CASE "A" RELEASE UUT.Start END_TEST_CASE |
SCLTEST_PARSE_RELEASE_ALL_EXPECT_SEMICOLON | RELEASE_ALL is missing ;. | TEST_CASE "A" RELEASE_ALL END_TEST_CASE |
SCLTEST_PARSE_WAIT_CYCLES_EXPECT_COUNT | WAIT_CYCLES is missing the count expression. | TEST_CASE "A" WAIT_CYCLES ; END_TEST_CASE |
SCLTEST_PARSE_WAIT_CYCLES_EXPECT_SEMICOLON | WAIT_CYCLES is missing ;. | TEST_CASE "A" WAIT_CYCLES 1 END_TEST_CASE |
SCLTEST_PARSE_WAIT_TIME_EXPECT_DURATION | WAIT_TIME is missing the duration expression. | TEST_CASE "A" WAIT_TIME ; END_TEST_CASE |
SCLTEST_PARSE_WAIT_TIME_EXPECT_SEMICOLON | WAIT_TIME is missing ;. | TEST_CASE "A" WAIT_TIME T#1s END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_LEFT | WAIT_UNTIL is missing the left expression. | TEST_CASE "A" WAIT_UNTIL = TRUE TIMEOUT T#1s; END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_OPERATOR | WAIT_UNTIL is missing its comparison operator. | TEST_CASE "A" WAIT_UNTIL UUT.Done TRUE TIMEOUT T#1s; END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_RIGHT | WAIT_UNTIL is missing the right expression. | TEST_CASE "A" WAIT_UNTIL UUT.Done = TIMEOUT T#1s; END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_TIMEOUT | WAIT_UNTIL is missing the TIMEOUT keyword. | TEST_CASE "A" WAIT_UNTIL UUT.Done = TRUE T#1s; END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_TIMEOUT_DURATION | WAIT_UNTIL TIMEOUT is missing the duration expression. | TEST_CASE "A" WAIT_UNTIL UUT.Done = TRUE TIMEOUT ; END_TEST_CASE |
SCLTEST_PARSE_WAIT_UNTIL_EXPECT_SEMICOLON | WAIT_UNTIL is missing ;. | TEST_CASE "A" WAIT_UNTIL UUT.Done = TRUE TIMEOUT T#1s END_TEST_CASE |
SCLTEST_PARSE_ASSERT_EXPECT_EXPR | ASSERT is missing its boolean expression. | TEST_CASE "A" ASSERT ; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_EXPECT_SEMICOLON | ASSERT is missing ;. | TEST_CASE "A" ASSERT UUT.Done = TRUE END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_LEFT | ASSERT_NEAR is missing its actual expression. | TEST_CASE "A" ASSERT_NEAR := 1 TOLERANCE 0.1; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_ASSIGN | ASSERT_NEAR is missing :=. | TEST_CASE "A" ASSERT_NEAR UUT.Value 1 TOLERANCE 0.1; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_RIGHT | ASSERT_NEAR is missing its expected expression. | TEST_CASE "A" ASSERT_NEAR UUT.Value := TOLERANCE 0.1; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_TOLERANCE | ASSERT_NEAR is missing TOLERANCE. | TEST_CASE "A" ASSERT_NEAR UUT.Value := 1 0.1; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_TOLERANCE_EXPR | ASSERT_NEAR TOLERANCE is missing its tolerance expression. | TEST_CASE "A" ASSERT_NEAR UUT.Value := 1 TOLERANCE ; END_TEST_CASE |
SCLTEST_PARSE_ASSERT_NEAR_EXPECT_SEMICOLON | ASSERT_NEAR is missing ;. | TEST_CASE "A" ASSERT_NEAR UUT.Value := 1 TOLERANCE 0.1 END_TEST_CASE |
SCL Test Semantic Checks
| Code | Meaning | Minimal trigger example |
|---|---|---|
SCLTEST_SEM_UNDECLARED | A test expression references an undeclared symbol. | ASSERT Missing = TRUE; |
SCLTEST_SEM_INVALID_PATH | A test expression uses an invalid designator path. | ASSERT UUT.StructValue.Missing = 1; |
SCLTEST_SEM_ASSIGN_TYPE | SET or HOLD assigns an incompatible type. | SET UUT.RealValue := T#1s; |
SCLTEST_SEM_RELEASE_WITHOUT_HOLD | RELEASE targets a variable that was not previously held. | RELEASE UUT.Start; |
SCLTEST_SEM_ASSERT_TYPE | ASSERT is not a BOOL expression or compares incompatible types. | ASSERT UUT.Count; |
SCLTEST_SEM_WAIT_CYCLES_TYPE | WAIT_CYCLES does not receive an integer-compatible expression. | WAIT_CYCLES T#1s; |
SCLTEST_SEM_WAIT_TIME_TYPE | WAIT_TIME does not receive TIME or LTIME. | WAIT_TIME 10; |
SCLTEST_SEM_TIMEOUT_TYPE | WAIT_UNTIL TIMEOUT does not receive TIME or LTIME. | WAIT_UNTIL UUT.Done = TRUE TIMEOUT 10; |
SCLTEST_SEM_COMPARE_TYPE | WAIT_UNTIL compares incompatible expression types. | WAIT_UNTIL UUT.Done = 1 TIMEOUT T#1s; |
SCLTEST_SEM_ASSERT_NEAR_TYPE | ASSERT_NEAR lacks an equality comparison or uses non-numeric operands/tolerance. | ASSERT_NEAR UUT.Done := TRUE TOLERANCE FALSE; |
SCLTEST_SEM_UNKNOWN_TARGET | TEST_TARGET does not resolve in the PLC scope. | TEST_TARGET "Missing_FB"; |
SCLTEST_SEM_TARGET_KIND | TEST_TARGET resolves to something other than a function or function block, or function metadata cannot load. | TEST_TARGET "SomeDataBlock"; |
LSP And Workspace Fallbacks
| Code | Meaning | Minimal trigger example |
|---|---|---|
LSP_ANALYZE_PIPELINE_ERROR | The LSP analysis pipeline failed before normal diagnostics could be published. | Internal failure while analyzing an opened PLC document. |
WORKSPACE_SCOPE_ERROR | A PLC workspace scope could not be resolved. | A broken .plc.json or unreadable scoped file prevents workspace indexing. |