Validation Reference
kuml validate checks a .kuml.kts script for structural integrity and OCL constraint
violations and reports all of them. It exits non-zero when any check fails, making it suitable
as a blocking CI step.
Synopsis
kuml validate [options] <script>
kuml validate takes one script per invocation. To check several, call it once per file, for
example in a shell loop.
Flag reference
| Flag | Default | Effect |
|---|---|---|
|
off |
Fail on any expression parse warning (guards, effects, parametric constraints) in addition to OCL violations. |
|
off |
Additionally validate stereotype applications: required properties and the OCL
constraints a custom profile attaches (e.g. |
|
off |
Skip structural checks (duplicate element IDs, circular inheritance, missing classifier references). Evaluate OCL constraints only. Useful when the structural issues are known and you only care about OCL correctness. |
|
off |
Skip the named-argument source-style check (calls into |
|
|
|
Exit codes
| Code | Meaning |
|---|---|
0 |
All checks passed — no structural violations, no OCL violations. |
2 |
Usage error — bad argument combination. |
3 |
Script error — compilation failed, missing imports, or the script threw at build time. |
4 |
I/O error — input file not found or unreadable. |
5 |
Validation error — at least one structural or OCL violation found. |
These codes are stable across kUML versions. CI scripts can branch on them.
Structural violation output
Structural checks run before OCL evaluation. They catch problems that would make OCL evaluation meaningless.
Example — duplicate element ID:
STRUCTURAL VIOLATION (duplicate-id)
Element : Class 'Order'
Location : classDiagram("Domain") → classOf("Order")
Message : Duplicate element id 'Order' — another classifier with the same name exists
in the same namespace.
Example — circular inheritance:
STRUCTURAL VIOLATION (circular-inheritance)
Element : Class 'A'
Location : classDiagram("Cycle") → generalization(A → B → C → A)
Message : Circular generalisation detected: A → B → C → A
Note validation output
For SysML 2, BPMN and ERM scripts (and UML comments) kuml validate prints a Note validation: section and
folds the findings into the structural part of the JSON output (category: "notes").
| Code | Severity | Meaning |
|---|---|---|
|
warning |
A note exceeds the display limit of 2000 characters / 30 lines and is rendered cut. The message names the note id and the limits, never the text. |
|
error |
A comment link points to an unknown comment or element. |
|
error |
A comment id collides with another element. |
|
warning |
An unanchored comment is listed in no diagram. |
|
error |
An association refers to an unknown annotation or element. |
|
warning |
The target is a pool, lane or sequence flow; not rendered. |
|
error |
A note link refers to an unknown note or element. |
|
error |
The anchor is neither an entity nor a view. |
kuml render prints the same findings as warnings on stderr and still renders.
OCL violation output
OCL violations appear after structural checks pass. Each violation prints:
-
The constraint name
-
The host classifier (the element that owns the constraint)
-
The OCL body
-
A short reason why evaluation returned false
Example:
OCL VIOLATION
Constraint : PositiveTotal
Host : Class 'Order'
Body : self.total >= 0
Reason : Invariant evaluated to false for instance 'order42' (total = -5.00)
JSON output (--format json)
With --format json, all violations are written to stdout as a JSON array:
[
{
"kind": "structural",
"code": "duplicate-id",
"element": "Order",
"location": "classDiagram(\"Domain\") → classOf(\"Order\")",
"message": "Duplicate element id 'Order' ..."
},
{
"kind": "ocl",
"constraint": "PositiveTotal",
"host": "Order",
"body": "self.total >= 0",
"reason": "Invariant evaluated to false ..."
}
]
An empty array [] is written when all checks pass (exit code 0).
CI integration example
The following GitHub Actions step fails the build on any validation violation:
- name: Validate kUML models
run: |
for f in docs/architecture/domain.kuml.kts docs/architecture/services.kuml.kts; do
kuml validate --strict "$f" || status=1
done
exit ${status:-0}
To capture structured output for a custom reporter:
- name: Validate and upload report
run: |
for f in src/**/*.kuml.kts; do
kuml validate --format json "$f" || true
done > kuml-violations.json
- name: Upload violation report
uses: actions/upload-artifact@v4
with:
name: kuml-validation-report
path: kuml-violations.json
Using || true prevents the step from failing so the artifact upload always runs.
The next step or the overall job can be configured to fail on a non-empty violations file.
|
Relationship to OCL constraints in scripts
Constraints are declared inside classifier or stereotype blocks:
classDiagram("Domain") {
val order = classOf("Order") {
attribute("total", "BigDecimal")
// Element-level constraint — evaluated by default
constraint("PositiveTotal", body = "self.total >= 0")
}
}
Profile-level constraints (in a KumlStereotype.constraints list) are only evaluated
when --strict is passed. See Profiles for how to author
stereotype constraints.
See also
-
Profiles — authoring stereotype constraints evaluated with
--strict -
OCL constraints — the OCL language supported by kUML
-
CLI Reference — full CLI flag reference