Skip to main content

Diagnostics

Every conformance diagnostic carries a stable code of the form DSL-<severity>-<area>-<number>. Search for the code — that is what it is for.

SeverityMeaning
EError. The document is rejected.
WWarning. Printed, and suppressible per code.
IInfo. Printed only with --style.

--strict promotes every warning to an error, which is what you want in CI. A model can also escalate specific codes itself through documentation.options.lint.error, or silence them through documentation.options.lint.silence — see Conformance flags.

This page lists what the compiler emits today

Codes are added as rules are implemented. If you meet a code that is not here, it is a bug in this page — please tell us. A CI check keeps the two in step, so it should not happen.

Engineering units

Units are validated against UNECE Recommendation 20, the same list the find_engineering_unit tool searches.

DSL-E-UNIT-001 — unknown unit

The symbol is not a UNECE Rec. 20 unit. The message suggests the closest known one.

engineeringUnits: "degree Celsius" # ✗ prose, not a symbol
engineeringUnits: "°C" # ✓

This is an error: an unknown unit would be written into the NodeSet2 as a unit no client can interpret.

DSL-W-UNIT-002 — ambiguous symbol

Several UNECE units share the symbol you wrote — V, MW and r/min are all ambiguous. The compiler resolves to the first deterministically and tells you which; the message lists the long names so you can be explicit.

DSL-W-UNIT-003 — near match

Not an exact symbol, but close enough to one that the compiler will use it. Write the exact symbol to silence this.

DSL-W-UNIT-004 — US spelling

You wrote a US spelling (meter); UNECE uses the international one (metre). The compiler uses the UNECE spelling.

Devices (DI) placement

The Devices companion specification is prescriptive about where things live on a di:ComponentType subtype. These fire only when your type derives from DI, and they are the most common finding in a first model.

DSL-W-DI-001 — process value outside ParameterSet

OPC 10000-100 (DI) v1.04 §4.3 — "the Parameters are components of the ParameterSet as a flat list of Parameters."

A Variable is declared directly on the type instead of inside the overridden di:ParameterSet.

- browseName: MySensorType
subtypeOf: di:ComponentType
components:
- browseName: Temperature # ✗ top-level process value
dataType: ua:Double
- browseName: MySensorType
subtypeOf: di:ComponentType
components:
- browseName: di:ParameterSet # ✓ redeclared, making it mandatory
components:
- browseName: Temperature
dataType: ua:Double

di:ParameterSet is optional on the base type; redeclaring it here is what makes it mandatory on every instance.

DSL-W-DI-002 — method outside MethodSet

The same rule for Methods: on a di:ComponentType subtype they belong inside the overridden di:MethodSet, not at the type's top level.

Naming

DSL-W-NAMING-005 — Structure DataType suffix

Model-Best v1.03 §2.1.3 — "For Structured DataTypes (subtypes of the Structure DataType) the suffix should be DataType."

ThreeDVector should be ThreeDVectorDataType.

Structure

DSL-W-STRUCT-006 — AddIn without a default browse name

OPC UA Part 3 v1.05 §4.10.3 — "The AddIn ObjectType shall include the definition of a default BrowseName using the DefaultInstanceBrowseName Property."

An AddIn ObjectType should declare DefaultInstanceBrowseName so instances can adopt it rather than each inventing a name.

Dependency versions

These two report on the companion specifications you import, and are not conformance rules — nothing in your model is wrong.

DSL-W-DEP-VERSION — major version differs

A nodeset was built against a different major version of a dependency than the one being loaded. Worth reading: a major bump can move or remove types.

DSL-I-DEP-VERSION — newer, same major

A dependency is newer than the one the nodeset was built against, within the same major version. Informational, and the normal state of affairs.

Silencing a diagnostic

Per code, or by prefix:

opcua-modeler generate -i model.yaml --silence DSL-W-NAMING-005,DSL-W-UNIT-

or in the model itself, so the decision travels with it:

documentation:
options:
lint:
silence: [DSL-W-NAMING-005]

Prefer fixing to silencing. A silenced warning is a decision, so leave a comment saying why — the next reader cannot see what you knew.