Diagnostic Codes

Reference for PLC diagnostics with minimal examples that trigger each code.

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_PARSE_TITLE_SEPARATOR A TITLE header line has no : or = after TITLE. TITLE Block name on the line after FUNCTION_BLOCK Demo.
SCL_PARSE_BLOCK_STORAGE_ATTRIBUTE S7_BlockNumber, S7_Optimized or S7_Optimized_Access has an invalid value or conflicts with an earlier setting on the same block. DATA_BLOCK D { S7_Optimized := "sometimes" } BEGIN END_DATA_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_AT_READ_ONLY_TARGET An AT overlay targets a project constant instead of writable storage. VAR_TEMP Overlay AT AXIS_COUNT : DINT; END_VAR
SCL_SEM_ASSIGN_UNDECLARED_TARGET An assignment writes to an undeclared target. Missing := 1;
SCL_SEM_ASSIGN_READ_ONLY_TARGET An assignment or FOR control variable tries to write to a project constant. AXIS_COUNT := 4;
SCL_SEM_INVALID_DESIGNATOR_PATH A designator path references a member or index that cannot exist. #StructValue.Missing := 1;
SCL_SEM_ABSOLUTE_ADDRESS An absolute address is malformed or not supported. #Flag := %DB1.DBX0.8;
SCL_SEM_DB_OPTIMIZED An absolute DB operand such as %DB7.DBX0.0 or P#DB7.DBX0.0 refers to a DB with optimized access. #q := %DB7.DBX0.0; with DATA_BLOCK D { S7_BlockNumber := 7; S7_Optimized := TRUE }
SCL_SEM_DB_AMBIGUOUS An absolute DB operand refers to a DB number that more than one DB in the PLC declares. %DB7.DBX0.0 when two data blocks both declare S7_BlockNumber := 7.
SCL_SEM_DB_UNVERIFIED Warns that an absolute DB operand refers to a DB whose block number or access mode the PLC sources do not declare. %DB7.DBX0.0 with DATA_BLOCK D { S7_BlockNumber := 7 } and no S7_Optimized setting.
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_SEM_INVALID_TIME_LITERAL A T#/TIME# literal does not parse (e.g. a us/ns component) or is outside the TIME range. #t := T#25d;
SCL_SEM_INVALID_LTIME_LITERAL An LT#/LTIME# literal does not parse or is outside the signed 64-bit nanosecond range. #lt := LT#106751d23h47m16s854ms775us808ns;
SCL_SEM_INSTANCE_METHOD_MISMATCH A timer/counter instruction is called on an intrinsic instance that does not provide it. #C.CTD(...) with C : CTU_INT
SCL_SEM_DURATION_ARITHMETIC TIME/LTIME arithmetic outside the TIA operand table (e.g. duration * duration, integer - duration, TIME + LINT). #t := #t * T#2s;
SCL_SEM_INVALID_DTL_LITERAL A DTL#... literal has an invalid calendar date, time, fraction, or supported range. #Stamp := DTL#2002-02-29-00:00:00;
SCL_SEM_INVALID_S5TIME_LITERAL An S5T#/S5TIME# literal does not parse, is negative, or exceeds 2h46m30s. #Preset := S5TIME#3h;
SCL_SEM_INVALID_BYTE_LITERAL A B#/BYTE# literal does not parse or does not fit in 8 bits. #b := BYTE#256;
SCL_SEM_INVALID_WORD_LITERAL A W#/WORD# literal does not parse or does not fit in 16 bits. #w := W#16#1_0000;
SCL_SEM_INVALID_DWORD_LITERAL A DW#/DWORD# literal does not parse or does not fit in 32 bits. #d := DW#16#1_0000_0000;
SCL_SEM_INVALID_LWORD_LITERAL An LW#/LWORD# literal does not parse or does not fit in 64 bits. #lw := LWORD#18446744073709551616;
SCL_SEM_INVALID_POINTER_LITERAL A P# pointer literal is malformed or out of range. #p := P#M0.8;
SCL_SEM_CALL_STATEMENT_ONLY A memory-write, bit packing or block transfer instruction is used as an expression, but these instructions return no value. #word := GATHER(IN := #bits, OUT => #word);
SCL_SEM_LIMIT_UNSUPPORTED A typed LIMIT_<type> call has the wrong inputs or an input type the runtime cannot adapt. #i := LIMIT_INT(0, #r, 10); where #r is REAL.
SCL_SEM_NUMERIC_INSTRUCTION_UNSUPPORTED A numeric instruction such as MIN, SEL, MUX, ABS, SQRT or ROUND has malformed inputs or operand types it does not support. #u := ABS(#u); where #u is UINT.
SCL_SEM_SHL_UNSUPPORTED A SHL call has malformed inputs, an IN that is not an integer or bit string, or an N count the runtime cannot convert. #w := SHL(TRUE, 1);
SCL_SEM_SHR_UNSUPPORTED A SHR call fails the same checks as SCL_SEM_SHL_UNSUPPORTED. #w := SHR(IN := #w);

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_CALL_INVALID_PIN A call mixes positional and named arguments, omits a required native input, or uses an association the callee does not support, such as EN/ENO on a native instruction. #Motor(TRUE, Stop := FALSE);
SCL_CALL_DUPLICATE_PIN A call assigns the same pin more than once. #Motor(Start := TRUE, Start := FALSE);
SCL_CALL_PIN_TARGET An output or in-out pin is connected to something that is not writable storage, or to an absolute address where the instruction needs symbolic storage. #Motor(Done => 1);
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_DUPLICATE_GLOBAL_NAME Tags or project constants in one XML table reuse the same global name. A tag and project constant are both named HAND.
TAGTABLE_TYPE_UNDEFINED A tag or project constant references a datatype not known in the PLC scope. A project constant uses MissingType.
TAGTABLE_GLOBAL_NAME_CONFLICT A tag or project constant conflicts with a global declaration in another file. HAND is declared in both Default tag table.xml and CONSTANTS.xml.

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.
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 Network Inventory

Code Meaning Minimal trigger example
S7DCL_NETWORK_LANGUAGE_UNKNOWN A NETWORK declares an unsupported explicit S7_Language. { S7_Language := "GRAPH" } NETWORK END_NETWORK

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_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_COMPARE_CONTACT_AFTER_BOOL A comparison contact follows an existing Boolean element in the same rung, a shape TIA may compile but cannot reopen graphically. RUNG #Enable EQ_Contact(in1 := #Value, in2 := 1) END_RUNG
S7DCL_FBD_CHAINED_COMPARE_CONTACT Multiple comparison contacts appear in series in one rung, a shape TIA cannot reopen graphically. RUNG GT_Contact(...) LT_Contact(...) END_RUNG
S7DCL_FBD_PIN_INLINE_BOOL_EXPR An FBD input pin contains a compound expression instead of a connected instruction block. RUNG TRUE MyFB(in1 := #Count > 0) END_RUNG
S7DCL_FBD_PIN_COMMENT A line or block comment in an FBD pin, between the pin name and the end of its expression. TIA rejects comments anywhere in a rung on import; each pin is reported once. RUNG TRUE MyFB(in1 := (* why *) #Start) END_RUNG
S7DCL_FBD_RUNG_COMMENT A line or block comment between NETWORK and END_NETWORK in an FBD network, outside a pin (S7DCL_FBD_PIN_COMMENT covers those): in a rung, between rungs, or on the NETWORK or END_RUNG line. TIA rejects these on import; comments outside NETWORK ... END_NETWORK are fine. RUNG TRUE (* why *) Coil(#Out) END_RUNG
S7DCL_FBD_META_MULTIPLE An FBD element has more than one metadata block in front of it. TIA rejects that on import even when each block is valid, so merge them into one block that lists each attribute once (TIA also rejects an attribute given twice). { S7_GenerateENO := "TRUE" } { S7_Templates := "time_type := Time" } #t.TON(PT := T#5s)
S7DCL_FBD_PIN_PARENTHESIZED_NOT An FBD pin inverts its operand with NOT (...); exported FBD pins spell inversion as NOT #operand without parentheses. RUNG TRUE MyFB(in1 := NOT (#Start)) END_RUNG
S7DCL_FBD_RUNG_HEADER_NOT An FBD rung starts with a negated operand. TIA's import requires an instruction or call after NOT, so negate the first element instead. RUNG NOT #Start Coil(#Out) 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_ALTERNATIVE_PATH Branches from one graphical source rejoin at different inputs of the same call or Boolean operator. An AND output feeds both REQ := wire#w1 and PERMIT := wire#w1 on one call, directly or through further Boolean boxes.
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

LAD networks run the same checks where they apply and report them with the S7DCL_LAD_ prefix, for example S7DCL_LAD_SEM_PIN_TARGET or S7DCL_LAD_DUPLICATE_INSTANCE_CALL.

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_UNKNOWN An FBD call uses a pin that is not defined by the resolved FB/FC interface. PID_Compact(NotAPin := TRUE)
S7DCL_FBD_SEM_PIN_DIR_MISMATCH An FBD call uses := or => against the wrong resolved pin direction. PID_Compact(Output := #Out)
S7DCL_FBD_SEM_PIN_NEGATION_INVALID A standalone NOT (an inverted, unconnected pin) is used on a pin that is not a BOOL input. MyFB(Count := NOT) where Count is INT.
S7DCL_FBD_SEM_PIN_MISSING An FBD call omits a required pin from the resolved FB/FC interface. PID_Compact(Setpoint := #SP) with other required pins omitted.
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_PIN_TARGET An FBD output or in-out pin is connected to an expression without writable storage. MyFC(Result => 1) or MyFC(State := #A + #B) for an in-out State.
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_EDGE_MEMORY_TYPE The edge memory operand of P_Trig or N_Trig is not BOOL. P_Trig(#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 Wires exported with END_RUNG wire#... feed each other in a cycle, so the transpiler emits a bounded fixed-point loop. RUNG wire#w2 END_RUNG wire#w1 and RUNG wire#w1 Coil(#out1) END_RUNG wire#w2
S7DCL_FBD_TX_WIRE_CYCLE Wires in a network with boxes, calls with wire outputs or inline wires depend on each other in a cycle, so the network has no execution order. RUNG wire#w1 #c.CTU(pv := 2) END_RUNG wire#w1
S7DCL_FBD_TX_UNDRIVEN_WIRE A network with boxes, calls with wire outputs or inline wires reads a wire that nothing in the network writes. RUNG wire#w1 #c.CTU(pv := 2) END_RUNG with no producer of wire#w1.
S7DCL_FBD_TX_TIMER_INSTANCE_UNRESOLVED A TONR call does not resolve to a TONR_TIME or IEC_TIMER instance. #t.TONR(IN := #Start, PT := T#5s) where #t is undeclared or a TON_TIME.
S7DCL_FBD_TX_COUNTER_INSTANCE_UNRESOLVED The instance type of a dotted counter call cannot be resolved. #c.CTU(pv := 2) where #c is undeclared.

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_RUNG_COMMENT A line or block comment between NETWORK and END_NETWORK in a LAD network: in a rung, between rungs, or on the NETWORK or END_RUNG line. TIA rejects these on import; comments outside NETWORK ... END_NETWORK are fine. RUNG wire#powerrail (* why *) Coil(#Out) END_RUNG
S7DCL_LAD_META_MULTIPLE A LAD element has more than one metadata block in front of it. TIA rejects that on import even when each block is valid, so merge them into one block that lists each attribute once (TIA also rejects an attribute given twice). { S7_GenerateENO := "TRUE" } { S7_Templates := "time_type := Time" } TON_Coil(timer => #t, pt := T#5s)

S7DCL LAD Semantic Checks

LAD networks also report the checks listed under S7DCL FBD Semantic Checks, with the S7DCL_LAD_ prefix.

Code Meaning Minimal trigger example
S7DCL_LAD_SEM_CONTACT_TYPE A contact operand is neither BOOL nor a legacy TIMER. Contact(#Counter) where #Counter is INT.
S7DCL_LAD_SEM_EDGE_INPUT_TYPE The operand input of a P_Contact or N_Contact combines non-Boolean operands. P_Contact(operand := #Flag AND #Counter, bit := #Mem) where #Counter is INT.

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 LAD wires depend on each other in a cycle, so the network has no execution order. RUNG wire#w1 P_Trig(#Mem) END_RUNG wire#w1
S7DCL_LAD_TX_UNDRIVEN_WIRE A rung reads a wire that nothing in the network writes. RUNG wire#w1 P_Trig(#Mem) END_RUNG with no producer of wire#w1.
S7DCL_LAD_TX_COMPARISON_OPERANDS A comparison contact is missing IN1 or IN2. EQ_Contact(in1 := #a)
S7DCL_LAD_TX_TIMER_INSTANCE_UNRESOLVED A TONR call does not resolve to a TONR_TIME or IEC_TIMER instance. #t.TONR(IN := #Start, PT := T#5s) where #t is undeclared or a TON_TIME.
S7DCL_LAD_TX_COUNTER_INSTANCE_UNRESOLVED The instance type of a dotted counter call cannot be resolved. #c.CTU(pv := 2) where #c is undeclared.
S7DCL_LAD_TX_TIMER_RESET_OPERAND An RT_Coil operand is not a single IEC timer instance, the coil is negated, or a project declaration shadows RESET_TIMER. RT_Coil(#Counter) where #Counter is INT.
S7DCL_LAD_TX_<instruction>_OPERAND A legacy timer coil or box has an unsupported, duplicate or negated pin, or an operand of the wrong kind. <instruction> is the element name: SD_COIL, SE_COIL, SD, SS or SF. IEC timer coils report S7DCL_<lang>_TX_<coil>_OPERAND. SD_Coil(Q => #Done) reports S7DCL_LAD_TX_SD_COIL_OPERAND.
S7DCL_LAD_TX_LABEL_INVALID A LAD network has more than one Label, a Label after its rungs, or a label that is not an identifier. NETWORK Label(a) Label(b) END_NETWORK
S7DCL_LAD_TX_LABEL_DUPLICATE Two networks in one block use the same label, ignoring case. Label(END) in one network and Label(end) in another.
S7DCL_LAD_TX_JUMP_TARGET_INVALID A JumpCoil target is missing or is not a plain label identifier. JumpCoil(#a)
S7DCL_LAD_TX_JUMP_TARGET_UNKNOWN A jump target is not a label in the same block. JumpCoil(missing)
S7DCL_LAD_TX_JUMP_PLACEMENT A network has more than one jump, a jump is not the last element of its rung, is negated or has an output wire, or an I_JumpCoil has no preceding logic. RUNG wire#powerrail JumpCoil(a) Coil(#q) END_RUNG
S7DCL_LAD_TX_SWITCH_PLACEMENT A network has more than one Switch jump distributor, or the Switch does not end the network's last rung. A Switch(...) followed by Coil(#q).
S7DCL_LAD_TX_SWITCH_<code> A Switch jump distributor is malformed. <code> is PINS, TARGET_INVALID, TARGET_UNKNOWN, TYPE_UNSUPPORTED or COMPARISON. Switch(k := 1, case0 := 1, dst0 => missing) with no Label(missing) in the block reports S7DCL_LAD_TX_SWITCH_TARGET_UNKNOWN.
S7DCL_LAD_TX_FLOW_LOOP_CONTROL A block with LAD jumps has EXIT or CONTINUE outside an SCL loop. A block with a JumpCoil also has an SCL network with a top-level EXIT;.

S7DCL FBD And LAD Instruction Lowering

These codes come from lowering instruction boxes in FBD and LAD networks. <lang> is FBD or LAD, so the same check reports S7DCL_FBD_TX_CONVERT_PINS in an FBD network and S7DCL_LAD_TX_CONVERT_PINS in a LAD network. Most families share these suffixes: TEMPLATE for an S7_Templates type the lowering does not take (a missing one is S7DCL_<lang>_TX_TEMPLATE_MISSING, one not in the form TIA exports S7DCL_<lang>_TX_TEMPLATE_SYNTAX, one that does not match the operands _TEMPLATE_MISMATCH or _TEMPLATE_CONVERSION), UNSUPPORTED for a type that is not implemented, PINS for missing, duplicate, unknown, misdirected or unwritable pins, and OPERAND_TYPE for an operand that does not match the instruction type.

Code Meaning Minimal trigger example
S7DCL_<lang>_TX_CONVERT_<code> A Convert box cannot be lowered. <code> is UNSUPPORTED, PINS or OPERAND_TYPE. UNSUPPORTED also covers pairs with a bit string other than DWord/Real and LWord/LReal, which TIA does not compile; for a bit string with an integer or another bit string, and for Char with Byte, the message points to Move. Convert(IN := #value, OUT => #result) with { S7_Templates := "[SrcType := Int, DestType := Byte]" } reports S7DCL_FBD_TX_CONVERT_UNSUPPORTED.
S7DCL_<lang>_TX_DIV_<code> A Div box with SrcType := DInt cannot be lowered. <code> is PINS or OPERAND_TYPE. Div(IN1 := #a, OUT => #q) with SrcType := DInt reports S7DCL_FBD_TX_DIV_PINS for the missing IN2.
S7DCL_<lang>_TX_LIMIT_<code> A Limit box cannot be lowered. <code> is TEMPLATE, PINS or OPERAND_TYPE. Limit(MN := 0, IN := #v, OUT => #q) with value_type := Int reports S7DCL_FBD_TX_LIMIT_PINS for the missing MX.
S7DCL_<lang>_TX_WORD_LOGIC_<code> A word AND or OR box cannot be lowered. <code> is TEMPLATE (a SrcType other than Byte, Word, DWord or LWord), PINS or OPERAND_TYPE. And(IN1 := #a, OUT => #q) with SrcType := Word reports S7DCL_FBD_TX_WORD_LOGIC_PINS for the missing IN2.
S7DCL_<lang>_TX_<shift>_<code> A SHL or SHR box cannot be lowered. <shift> is SHL or SHR, and <code> is UNSUPPORTED (a SrcType other than a bit string or integer type), PINS or OPERAND_TYPE. SHL(IN := #v, N := 1, OUT => #q) with SrcType := Real reports S7DCL_FBD_TX_SHL_UNSUPPORTED.
S7DCL_<lang>_TX_<op>_<code> An Add or Mul box evaluated as DInt or Real cannot be lowered. <op> is ADD or MUL, and <code> is PINS or OPERAND_TYPE. ADD(IN1 := TRUE, IN2 := 1, OUT => #Result) with SrcType := DInt reports S7DCL_FBD_TX_ADD_OPERAND_TYPE.
S7DCL_<lang>_TX_MOVE_OPERAND_TYPE A MOVE box reads or writes a BOOL operand, which TIA does not compile ("Data type Bool is not permitted here."). MOVE(IN := FALSE, OUT1 => #flag) where #flag is BOOL.
S7DCL_<lang>_TX_<op>_PINS A selection, math or rounding box has an invalid pin or no connected output, or a Mux or Demux box has no ELSE pin, which TIA's import requires (the pin may be blank, and TIA accepts it in either direction). <op> is the box name: SEL, MUX, DEMUX, MIN, MAX, MOD, ABS, SQR, SQRT, LN, EXP, FRAC, EXPT, ROUND, TRUNC, CEIL, FLOOR, NORMALIZE, SCALE_X or SCALE. MIN(IN1 := #a, IN2 := #b) with value_type := Int reports S7DCL_FBD_TX_MIN_PINS.
S7DCL_<lang>_TX_INSTRUCTION_NAME A box uses a name that TIA's import does not accept as an instruction: a conversion function such as USINT_TO_REAL, INT_TO_BOOL or CHAR_TO_INT (the message names the Convert templates or Move where TIA compiles one of them for the pair and plccheck lowers it, and no replacement otherwise; neither takes Bool), Norm_X (use Normalize), or In_Range/Out_Range (use InRange/OutRange). A project block named Norm_X, In_Range or Out_Range is called as a block instead. TIA reads conversion names with a string or date/time side, such as INT_TO_STRING, as S_Conv and T_Conv, so they are not reported, except those with a Bool side (BOOL_TO_STRING, TIME_TO_BOOL) and WCHAR_TO_STRING, which TIA does not read that way. USINT_TO_REAL(IN := #small, OUT => #value)
S7DCL_<lang>_TX_BIT_PACKING_TYPE The template type of a GATHER or SCATTER box is not BYTE, WORD, DWORD or LWORD, or does not match the packed operand. GATHER with dest_type := Word writes OUT to a DWORD.
S7DCL_<lang>_TX_EDGE_OPERANDS An edge instruction has no single edge memory operand, or a P_Contact/N_Contact is missing its operand or bit pin. P_Trig(#a AND #b)
S7DCL_<lang>_TX_LATCH_OPERANDS An S_SR or S_RS latch is missing operand or its second input, uses a non-designator operand, or has extra pins. S_RS(operand := #a)
S7DCL_<lang>_TX_WIRE_OUTPUT_TYPE A call output pin of a type other than BOOL is connected to a wire. MyFB(Count => wire#w1) where Count is INT.
S7DCL_<lang>_TX_TEMPLATE_MISSING A box has no S7_Templates value for a key TIA requires (or NotChosen or ???), so TIA asks to select a data type. SrcType on comparison contacts, InRange, OutRange, Mux, Demux, Abs, Neg, Sqr, Sqrt, Ln, Exp, Sin, Cos, Tan, Asin, Acos, Atan, Frac, And, Or, Xor, Inv, Shl, Shr, Rol, Ror and Swap; SrcType and DestType on Expt, Round, Trunc, Ceil, Floor, Convert, Normalize and Scale_X; value_type on Sel, Min, Max, Limit and CTU, CTD and CTUD instance calls. Add, Sub, Mul, Div and Mod need SrcType only when every input is an untyped literal; with a typed input TIA infers the type when there is no template or one that sets SrcType (even to NotChosen), and a template without SrcType is reported. Also reported for any key besides value_type on Min and Max. Counter calls in safety blocks are not checked. Abs(in := #r, out => #q) without { S7_Templates := "SrcType := Real" } before it.
S7DCL_<lang>_TX_TEMPLATE_MISMATCH A box template does not match its operands, and TIA fails the compile: the SrcType of a comparison contact, InRange or OutRange that a typed input does not convert to without losing its sign or accuracy (Int for a UInt or Real input, Real for an LReal one), a SrcType or DestType of Convert, Round, Trunc, Ceil or Floor other than the type of a numeric IN or OUT (DInt for an Int input; a bit-string IN or OUT passes a SrcType or DestType of its width, Word for Int and DWord for Real), an integer SrcType of any of these with a real literal on its pins, which TIA reads as LReal (1.5 with SrcType := DInt), an integer SrcType of a comparison contact, InRange or OutRange too small for an integer literal on its pins (40000 with SrcType := Int), a Convert whose SrcType and DestType are the same Real, LReal, bit-string, Char or WChar type (TIA: "both data types are the same"; integer pairs compile), a value_type on a CTU, CTD or CTUD call that does not select the instance type (Int for CTU_INT and IEC_COUNTER), a Bool or bit-string SrcType on Add, Sub, Mul, Div or Mod (SrcType := Word), or a Real or LReal template on any box with an untyped integer literal on its pins, since TIA takes no integer literal on a Real pin (write 0.0). Other untyped literals and inputs of other or unknown types are not checked. EQ_Contact(in1 := #a, in2 := #b) with { S7_Templates := "SrcType := Int" } where #a is UInt.
S7DCL_<lang>_TX_TEMPLATE_CONVERSION Warning. The SrcType of Abs, Add or Mux, or the value_type of Min, Max, Sel or Limit, does not take a typed input without losing its sign or accuracy. TIA compiles the box and converts the input to the template type. plccheck tests convert it too, except on Add with a SrcType other than DInt or Real. A Real or LReal template with an integer literal on its pins is _TEMPLATE_MISMATCH instead. Abs(in := #r, out => #q) with { S7_Templates := "SrcType := Int" } where #r is Real.
S7DCL_<lang>_TX_TEMPLATE_SYNTAX An S7_Templates on any FBD or LAD element is not in the form TIA exports: "Key := Type" or "[Key := Type, Key := Type]", double-quoted and spaced exactly like that, each key once in TIA's case (time_type, not TIME_TYPE; SrcType, not srctype). plccheck is stricter than TIA, which accepts or repairs some other forms. { S7_Templates := "time_type:=Time" } before #t.TON(PT := T#1s).
S7DCL_<lang>_TX_<coil>_OPERAND An IEC timer coil has an unsupported, duplicate or negated pin, an operand of the wrong kind, a timer instance that does not resolve or is not an IEC timer type providing its instruction, or a negation: any in LAD, a postfix NOT in FBD (a prefix NOT inverts the timer's IN). <coil> is the element name: TP_COIL, TON_COIL, TOF_COIL, TONR_COIL or PT_COIL. TON_Coil(Q => #Done) reports S7DCL_FBD_TX_TON_COIL_OPERAND in FBD; the coil only has TIMER and PT pins (or OPERAND := and VALUE :=).
S7DCL_<lang>_TX_TIMER_TEMPLATE A TP, TON, TOF or TONR call or TP_Coil, TON_Coil, TOF_Coil or TONR_Coil on an IEC timer instance has a time_type TIA rejects. On every CPU: an S7_Templates with other keys but no time_type, which fails the import of a call and the compile of a coil (other keys next to time_type are fine). On coils on every CPU, and on calls when .plc.json sets cpuFamily to S7-1500 or S7-1200 G2 outside safety blocks: no S7_Templates, time_type := NotChosen (or ???), or a time_type that does not match the instance: Time for IEC_TIMER and the _TIME types, LTime for IEC_LTIMER and the _LTIME types. #t.TON(PT := T#1s) on a TON_TIME instance without { S7_Templates := "time_type := Time" } before it.

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.
PLCJSON_CPU_FAMILY_INVALID .plc.json sets a cpuFamily other than S7-1200, S7-1200 G2, S7-1500 or S7-300/400. The family is treated as unknown, so CPU-specific checks are skipped. check reports it as an error, and test, generate, compile and run print it as a warning. "cpuFamily": "S7 1500"