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)​

The Devices companion specification (OPC 10000-100) is prescriptive about where things live: process values and methods on a di:ComponentType subtype, the nodes a FunctionalGroup organizes, the Devices in DeviceSet, the Networks in NetworkSet. These run only on a model that imports DI (the DI extension, ADR-010), and DSL-W-DI-001 is the most common finding in a first model. Each cites the sentence of OPC 10000-100 v1.05 it enforces: a "shall" is an error, a "should" a warning.

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.

DSL-E-DI-003 — a FunctionalGroup organizes two nodes with the same name​

OPC 10000-100 §4.4.1 — "All BrowseNames for Nodes referenced by a FunctionalGroup with an Organizes Reference shall be unique."

A client finds an element of a FunctionalGroup by its BrowseName: two Speed variables, one from ParameterSet and one from elsewhere, make that ambiguous. Organize one of them only.

DSL-W-DI-005 — a FunctionalGroup organizes a node of another element​

OPC 10000-100 §4.4.1 — "Organizes References should be used when the elements are components in other parts of the TopologyElement that the FunctionalGroup belongs to."

The group organizes a node that is not part of the Device (TopologyElement) it belongs to, for instance a parameter of another Device.

DSL-W-DI-006 — a Device that DeviceSet does not reach​

OPC 10000-100 §4.9 — DeviceSet "shall either directly or indirectly reference all instances of a subtype of ComponentType with a Hierarchical Reference."

DI clients find Devices from DeviceSet: place the instance with organizedBy: /ua:Objects/di:DeviceSet, or under a Device that is there. A warning, not an error, because some companion specifications place their components under folders of their own.

DSL-E-DI-007 — a component of a composed Device is in DeviceSet too​

OPC 10000-100 §4.9 — "only the root instance shall be referenced from the DeviceSet Object."

A Device that is a component of another Device is reached through it; referencing it from DeviceSet as well lists it twice.

DSL-E-DI-008 — a Network outside NetworkSet​

OPC 10000-100 §5.6 — "All Networks shall be components of the NetworkSet Object."

Declare the Network with componentOf: /ua:Objects/di:NetworkSet.

DSL-E-DI-009 — a ConnectionPoint no Device holds​

OPC 10000-100 §5.4 — "the ConnectionPoints shall have the inverse Reference (ComponentOf) to the Device."

A ConnectionPoint is how a Network reaches a Device: declare it as a component of the Device.

DSL-E-DI-010 — a Lock no owner holds​

OPC 10000-100 §7.3 — "It shall be referenced using HasComponent or HasAddIn from the lock-owner Object."

A di:LockingServicesType Object belongs to what it locks, usually a Device: declare it as a component (or an AddIn) of that Device.

DSL-E-DI-101 — a di: block with a key it does not know​

A di: block holds exactly one kind, device, component, block or topologyElement, and each takes parameters, methods, groups, identification, nameplate and lock (see the DI vocabulary). On an instance it takes only values, nameplate and parameters, and the instance names its typeDefinition.

DSL-E-DI-102 — a di: group member that names nothing​

A member of a group, or of identification, is a parameter or a method of the same block, or a nameplate Property (Manufacturer, SerialNumber, …). Another element of the type is written as a path: /Range.

DSL-E-DI-103 — a nameplate name the block cannot make Mandatory​

nameplate: lists Optional nameplate Properties of DI to make Mandatory. On a device, the eight of OPC 10000-100 §4.7 (SerialNumber, Manufacturer, Model, …) are Mandatory already.

Naming​

DSL-E-NAMING-001 — a browse name that is not an identifier​

OPC UA Part 3 v1.05 §6.4.4.4.4 recommends angle brackets on a placeholder

A browse name chosen by the model must be letters, digits and underscores, starting with a letter; a placeholder is written <Name>, alone or inside a name. OPC UA itself accepts any string, but a name with spaces, slashes or # cannot be written in a browse path, a generated symbol or most client code.

- browseName: <User defined Input#> # ✗
- browseName: <UserDefinedInput> # ✓
- browseName: Port<n> # ✓ a numbered member

A name with a namespace prefix (di:Manufacturer, ua:<OrderedObject>) belongs to another specification and is not checked. When a published NodeSet is projected as it is (tolerant mode, spec-repo pull), the finding is a warning, written as a comment above its line.

DSL-W-NAMING-003 — type browse name without the Type suffix​

Model-Best v1.03 §2.1.3 — "The BrowseName of a TypeDefinitionNode should have the suffix Type."

An ObjectType or VariableType whose browse name does not end in Type. The suffix is what lets a reader tell a type from an instance at a glance, and it is near-universal in the published companion specifications.

SomeObject → SomeObjectType. Interface types are not exempt: the convention there is I…Type, as in IVendorNameplateType.

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.

Raised only when the add-in type belongs to your model, where you can fix it. Attaching a type from another namespace that you cannot change — ua:FolderType, as OPC 40001-1 Machinery does for MachineryBuildingBlocks — with an explicit browseName: is reported as information instead.

DSL-W-STRUCT-009 — inherited member restated​

OPC UA Part 3 v1.05 §6.4.4

A member inherited from the parent's typeDefinition restates its nodeClass or its typeDefinition identically. It adds nothing and is ignored — only a redeclaration that changes something has an effect.

Remove the line. If you meant to narrow the type, give a typeDefinition that is a subtype of the inherited one.

DSL-E-STRUCT-010 — inherited member contradicted​

OPC UA Part 3 v1.05 §6.4.4

A subtype may refine an inherited member, not contradict it. This is raised when the redeclaration changes:

  • the nodeClass — it is fixed by the declaration you inherit from;
  • the typeDefinition to something that is not a subtype of the inherited one;
  • a Mandatory member's modelling rule to something weaker.

Remove the conflicting key, or make the typeDefinition a subtype of the one you inherit.

DSL-W-STRUCT-011 — browse path does not resolve​

OPC UA Part 4 v1.05 §5.8.4

A browse path could not be followed from its starting node — one of its steps matches nothing.

The usual cause is an Optional member that was never activated: an optional member only exists once something asks for it, so a path through one that was not listed in optionals: has nothing to traverse. Check each step of the path, and that every optional step on it is actually materialised.

DSL-W-STRUCT-012 — modellingRule where there is nothing to govern​

OPC UA Part 3 v1.05 §6.4.4

modellingRule on a node whose parent is not an ObjectType or VariableType. A ModellingRule governs an InstanceDeclaration, which only exists under a type; on a member of an ordinary Object or Variable there is none, so the key is ignored.

Remove it — or move the member under the type, if it was meant to be part of the type's definition.

DSL-E-STRUCT-013 — a Method that nothing owns​

OPC UA Part 3 v1.05 §5.7.1

A Method declared under organizes:. A Method shall be the target of at least one HasComponent from an Object or ObjectType; a folder may organize a Method, but only one that some node owns. Declare it where it belongs, and organize it with a reference:

objectTypes:
- browseName: MyControlFunctionType
components:
- browseName: Operational
typeDefinition: di:FunctionalGroupType
organizes:
- browseName: Stop # ✗ a Method with no owner
nodeClass: Method
references: # ✓ the state machine's own Stop
- referenceType: ua:Organizes
source: /Operational
target: /ControlFunctionState/Stop

The target must exist in the type: a method the state machine only inherits from its own type is not a node of this one, so redeclare it (under the state machine member's methods:) before organizing it.

The reverse writes this form only when the NodeSet itself declares such a Method, as OPC 30500 LADS 1.0.0 does for six of them: the finding is then about the published NodeSet. When such a NodeSet is projected as it is (tolerant mode, spec-repo pull), the finding is a warning, written as a comment above its line, and the Method is built as a component of the folder.

DSL-W-STRUCT-014 — an instance with no parent​

OPC UA Part 3 v1.05 §5.2.1

An instances: entry with none of organizedBy, componentOf or propertyOf. It is built as declared, but no hierarchical reference reaches it: a client browsing from the Objects folder never finds it. Give it a parent:

instances:
- browseName: Configuration
typeDefinition: di:FunctionalGroupType
organizedBy: /ua:Objects # ✓ reachable

The reverse writes this form only when the NodeSet declares such a node, as OPC 10000-100 DI does for its design-tool FunctionalGroups (Configuration, Tuning, …): leaving it out would renumber it, and its NodeId is part of the companion specification.

DSL-W-NS-005 — member shadows an inherited one​

OPC UA Part 3 v1.05 §4.1

A declared member has the same name as an inherited member but a different namespace, so both exist side by side. A BrowseName is qualified by its namespace, which makes this legal — and easy to miss, because the two read identically unless you look at the prefix.

If you meant to refine the inherited member, use its namespace prefix. If you meant a genuinely new member, a distinct name will save the next reader.

DSL-W-STRUCT-007 — Property reachable only through a Folder​

OPC UA Part 3 v1.05 §4.4.2 — "Properties are defined using the HasProperty Reference."

A Property is reachable only by an Organizes reference from a Folder, with no HasProperty from the Node it belongs to. A Folder may organize a Property it does not own, but the owning Node still has to declare it — otherwise a client browsing the Node never sees the Property.

DSL-W-STRUCT-008 — optionals: on a type​

OPC UA Part 3 v1.05 §6.4.4

optionals: on a type has no effect and was discarded. A type's members are inherited from its supertype already carrying their own modelling rule; optionals: only means something where a typeDefinition is instantiated. To make an inherited member Mandatory on a type, use promotedToMandatory:.

Reference types​

DSL-E-DT-009 — dataType where typeDefinition belongs​

OPC UA Part 3 v1.05 §4.4

dataType: names something that resolves to an ObjectType. A Variable has a DataType; an Object has a TypeDefinition. These are the two being confused, and the node would end up with neither.

components:
- browseName: MyComponent
dataType: MyObjectType # ✗
typeDefinition: MyObjectType # ✓

DSL-W-REF-004 — inverseName omitted​

OPC UA Part 3 v1.05 §5.3.3

An asymmetric ReferenceType named Has<X> declared no inverseName, so Is<X>Of was derived and used. The model still builds, but the generated NodeSet carries a name nobody chose — write it explicitly if the derived one is not what you mean.

DSL-W-REF-003 — inverseName differs from the convention​

OPC UA Part 3 v1.05 §5.3.3

A Has<X> ReferenceType whose inverseName is neither <X>Of nor Is<X>Of. The standard uses both: <X>Of for its core references (HasComponent / ComponentOf, HasProperty / PropertyOf, HasSubtype / SubtypeOf) and Is<X>Of for others (HasCondition / IsConditionOf). Another name makes the relationship read as something other than it is. Deliberate departures are fine — this is a warning, not an error (HasCause / MayBeCausedBy is one the standard makes itself).

Keys and lists​

These are about the modelling language itself rather than OPC UA. Each one catches something that would otherwise be skipped without a word, leaving a model that builds but is not the one you wrote.

DSL-E-KEY-001 — unknown key on a member or an entry​

A component, property, method or other member, or an entry of a section such as objectTypes: or instances:, carries a key it does not accept. The key is never read, so whatever it was meant to set keeps its default:

components:
- browseName: Pressure
dataType: ua:Double
modelingRule: Optional # ✗ one L — the member stays Mandatory
modellingRule: Optional # ✓
objectTypes:
- browseName: PressBaseType
isAbstact: true # ✗ one R missing — the type stays concrete
isAbstract: true # ✓

When the key is close to a real one the message names it (do you mean modellingRule instead ?). When nothing is close it says so rather than guess. An objects: entry is created as written, so an instance key such as dataType or optionals is reported there with a pointer to instances:.

An ObjectType or VariableType entry with a nested subtypes: list gets the same error. A subtype is always its own entry naming its parent with subtypeOf:

objectTypes:
- browseName: MachineType
- browseName: MillType
subtypeOf: MachineType # ✓ not `subtypes:` under MachineType

DSL-W-KEY-002 — unknown top-level key​

A key at the root of the document that the model does not define, most often a misspelt section name such as objectType:. Nothing reads it, so every entry under it is missing from the generated NodeSet. It is a warning because a stray key is harmless in itself; under --strict it is an error.

DSL-E-KEY-003 — a list was expected​

A section (objectTypes, dataTypes, instances, …) or a member list (components, properties, methods, …) is a mapping or a single value. Each holds a YAML list, one item per node, named by its browseName:

objectTypes:
HydraulicPressType: # ✗ keyed by name: none of it is read
subtypeOf: di:DeviceType

objectTypes:
- browseName: HydraulicPressType # ✓
subtypeOf: di:DeviceType

Until this diagnostic existed the first form produced no output and no message: a model written that way validated as correct while defining nothing.

A string under organizes: links a node declared elsewhere (see Organizes links). Inside a type, $Name names the member of that type whose BrowseName is Name.

Two or more members of the type carry that BrowseName, at different depths, so the link would be a guess. The message lists each one with its path from the type. Write the path of the one you mean, or give it an $anchor:

- browseName: Limits
typeDefinition: ua:FolderType
organizes: [$Speed] # ✗ Axis1/Speed or Axis2/Speed?
organizes: [/Axis2/Speed] # ✓ the path from the type
organizes: [$Axis2Speed] # ✓ with `$anchor: Axis2Speed` on that member

No member of the type, declared or inherited, has that BrowseName: usually a typo. Members with a close name are suggested, with their paths. No reference is made.

DSL-E-PERM-001 — role not found​

The role: of a rolePermissions: entry is not a RoleType instance. A short name is looked up among roles only, in the namespace its prefix names; a leading / takes a full browse path instead:

rolePermissions:
- role: ua:Operater # ✗ no role has that name; the message lists the ones that exist
permissions: [Browse]
- role: ua:Operator # ✓ an ns0 role, by its BrowseName
permissions: [Browse, Read]
- role: MaintenanceRole # ✓ a role this model declares
permissions: [Browse, Call]

Use the BrowseName (ua:Operator), not the SymbolicName WellKnownRole_Operator. The entry is left out, so the node grants that role nothing.

DSL-E-PERM-002 — not a permission name​

A permissions: name that is not a PermissionType bit, or an accessRestrictions: name that is not an AccessRestrictionType bit. Both sets are OPC UA's own, so the names take no namespace prefix:

permissions: [Browse, ns:Something] # ✗ a prefix points at nothing
permissions: [all, Read] # ✗ all stands alone
permissions: [Browse, Read, Call] # ✓
permissions: [all] # ✓ every permission valid for the node's NodeClass
accessRestrictions: [SigningRequired, EncryptionRequired]

DSL-E-PERM-003 — permission set not usable​

A permissionSet: names no entry of permissionSets:, or the node also writes rolePermissions: or accessRestrictions: itself. A node takes its permissions from one place:

permissionSets:
adminOnly:
rolePermissions:
- role: ua:SecurityAdmin
permissions: [all]
accessRestrictions: [SigningRequired, EncryptionRequired]
...
- browseName: Secret
permissionSet: adminOnly # ✓
- browseName: Key
permissionSet: adminOnly # ✗ a set and its own keys
accessRestrictions: [SigningRequired]

DSL-W-PERM-004 — permission set not used​

No node names this permissionSets: entry, so it grants nothing. Check the nodes meant to use it for a misspelt name: those are reported as DSL-E-PERM-003.

Model file form​

These describe the shape of the file, not the model in it. A model can be perfectly valid and still draw one.

DSL-W-FORM-KIND-IN-HEAD — kind: in the model document​

kind: opens a tail document of a self-contained stream; document 1 is the model and is marked profile: self-contained instead. A stray kind: in the head flips generate onto the stream path with no table to read.

Put a --- separator before the line so it opens a tail document, delete it, or let opcua-modeler pack write the tail.

DSL-W-FORM-NOT-SEALED — .opcua.yaml with no sealed table​

The file carries the self-contained extension but holds no kind: symbols document, so NodeIds are still read from and written to the .csv sidecar rather than the file itself.

Run opcua-modeler pack to seal the table in, or rename it back to *.model.yaml to keep the pair form.

DSL-I-FORM-MISNAMED — sealed stream not named .opcua.yaml​

The file is a sealed self-contained stream but is not named *.opcua.yaml, so editors bind the single-document model schema to it and flag every line of a perfectly correct tail.

DSL-W-FORM-ORPHAN-CSV — sidecar beside a sealed stream​

A .csv symbol file sits next to a sealed stream. The embedded table is the only ledger that is read; the CSV is ignored and will drift out of date.

Doctor — file and ledger health​

opcua-modeler doctor reports these. They are about NodeId stability across regenerations, which is what keeps a published NodeSet's ids meaningful.

DSL-E-DOCTOR-MISSING — file does not exist​

A file named on the command line is not there.

DSL-E-DOCTOR-STREAM-PARSE — stream does not parse​

The file looks like a self-contained stream but does not parse. Check the --- separators and the kind: key of each tail document.

DSL-W-DOCTOR-NO-OWN-TABLE — no table for its own namespace​

The file is a stream, but none of its kind: symbols documents is for its own namespaceUri — so every NodeId is allocated afresh on the next generate.

DSL-W-DOCTOR-LEDGER-STALE — table sealed against an older model​

Nodes added since have no id yet; nodes removed since are still listed. Not fatal — generate re-seals — but worth knowing before a release rather than after.

DSL-E-DOCTOR-DUPLICATE-ID — one id, two nodes​

The same NodeId is assigned to two different browse names. Give one of them a fresh id by hand, regenerate, and compare the NodeSet2.xml.

DSL-E-DOCTOR-RECYCLED-ID — a retired id came back​

An id is both retired and live. Retirement exists precisely to stop this: a client that cached the old node now resolves it to a different one. Move the live node to a fresh id above nextId.

DSL-E-DOCTOR-NEXTID — nextId is already in use​

nextId is at or below an id that is already assigned or retired, so the next node added would collide. Raise it above the highest id in use.

DSL-I-DOCTOR-NO-LEDGER — no symbol file​

A pair-form model with no .csv. Every NodeId is allocated from scratch on the next generate — harmless the first time, a renumbering of a published NodeSet every time after. Generate once and keep the ledger under version control, or pack to the self-contained form.

DSL-W-DOCTOR-OUTPUT-STALE — NodeSet older than the model​

The generated .NodeSet2.xml is older than the model it came from, so it does not describe the current model.

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.

OPC UA FX​

These rules come from the OPC UA FX extension (@sterfive/opcua-modeler-ext-fx, ADR-010). They check a model that imports fxData, fxAc or fxCm against OPC 10000-81 once it is compiled, and point at the node that breaks the rule. An error is a "shall" of the specification; a warning is a recommendation, or a requirement that holds only in some deployments.

DSL-E-FX-001 — FunctionalEntities holds only FunctionalEntities​

OPC 10000-81 §6.2.2, Table 4 — the FunctionalEntities Folder holds only instances of a FunctionalEntityType subtype, or of a type implementing IFunctionalEntityType.

Move the node to the Assets folder if it is hardware, or give it a FunctionalEntity type.

DSL-E-FX-002 — Assets holds only Assets​

OPC 10000-81 §6.2.2, Table 4 — the Assets Folder holds only instances of FxAssetType or a subtype, or of a type implementing the vendor and tag nameplates and IAssetRevisionType.

DSL-E-FX-003 — an Asset a FunctionalEntity uses is listed in Assets​

OPC 10000-81 §6.2.2, Table 4 — Assets "shall include all assets that are referenced from the FunctionalEntities".

A FunctionalEntity names the Asset it runs on with IsHostedBy (or IsExecutingOn); organize that Asset in the AutomationComponent's fxAc:Assets folder. A built-in part of a listed Asset (HasBuiltInAsset) counts as listed.

DSL-E-FX-004 — what an Inputs or Outputs folder may hold​

OPC 10000-81 §6.4.4, §6.4.5 — InputData holds only Variables, SubscriberCapabilities or nested <InputGroup>; OutputData only Variables, PublisherCapabilities or nested <OutputGroup>.

Group related Variables in a nested folder of type fxAc:InputsFolderType or fxAc:OutputsFolderType rather than an Object.

DSL-E-FX-005 — unique Variable names in an Inputs or Outputs folder​

OPC 10000-81 §6.4.4, §6.4.5 — the BrowseNames of the Variables in the folder shall be unique.

Two Variables differing only by namespace count as the same name. A nested group separates them.

DSL-W-FX-006 — String and ByteString data need a maximum length​

OPC 10000-81 §6.4.4, §6.4.5 — with PubSub periodic data in a fixed layout, a String Variable carries MaxStringLength, a ByteString Variable MaxByteStringLength.

A warning, since only a fixed-layout exchange requires it; declare the property to keep the model usable there.

DSL-W-FX-007 — an AutomationComponent goes under FxRoot​

OPC 10000-81 §12.2 — FxRoot is the standard entry point for all instances related to OPC UA FX.

Use organizedBy: /ua:Objects/fxData:FxRoot.

DSL-W-FX-008 — one ConnectionManager per Server​

OPC 10000-81 §12.3 — a Server supporting a ConnectionManager has only one instance.

fxCm already provides it, as FxRoot/ConnectionManager: do not declare another one.

DSL-E-FX-101 — an fx: block with a key it does not know​

An fx: block holds exactly one of functionalEntity, automationComponent and asset, and each takes its own keys (see the FX vocabulary). An instance takes automationComponent only, the other two describe types; it may also state its links, hostedBy and executingOn, each one path or a list of paths.

DSL-E-FX-102 — an fx: name that names nothing​

A name in a ControlGroup's restrict, block or related is one of the FunctionalEntity's own inputs, outputs, configuration variables or methods (or a path containing /). A hostedBy or executingOn on a type names an asset of the same automationComponent block.

DSL-E-FX-103 — an author version that is not Major.Minor.Build.SubBuild​

author: { version: 1.0.0.0 } becomes the FxVersion structure of AuthorAssignedVersion (OPC 10000-81 §6.4.2): four whole numbers separated by dots.

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.