CLI Reference

The CLI is the most direct way to use kUML — render, watch, generate, validate, simulate, import, export, reverse-engineer, and run models. Every subcommand prints its own help with --help; kuml --help lists them all.

Synopsis

kuml <subcommand> [options] <input>

Options available on every command:

  • --version — print version and exit (on the bare kuml command)

  • --help / -h — print the help of the command or subcommand

Most commands take a single *.kuml.kts script as input. To process several scripts, call the command once per file (for example from a shell loop or from the Gradle plugin).

kuml render

Render a script to SVG, PNG, LaTeX/TikZ or an animation.

kuml render [options] <script>

Options:

  • -o, --output <path> — output file

  • -f, --format svg|png|latex|tex|apng|webp|mp4 — default svg. latex / tex emit TikZ output (UML, SysML 2, C4, and BPMN are all supported). apng, webp and mp4 export an animation (see --animated); webp and mp4 need img2webp or ffmpeg on the PATH.

  • --theme <name> — theme name (kuml, plain, elegant, playful); the default is kuml. Overrides kuml.config.kts.

  • --layout auto|elk|grid — layout engine override. auto (the default) uses ELK for every diagram type; grid opts in to the experimental kuml.grid engine.

  • -w, --width <pixels> — PNG width (height is derived from the aspect ratio)

  • --config <path> — load a kuml.config.kts file

  • --animated — emit an animated SMIL SVG (state machines and activities; see SMIL Animation). --trace <path> supplies a kuml.trace.v1 file for trace-driven animation (without it a demo sequence is synthesised); --speed <factor> sets the playback speed.

  • --latex-standalone — emit a complete compilable LaTeX document instead of a bare tikzpicture snippet (only with --format latex).

  • --notation martin|bachman|chen|idef1x — ERM notation override (ERM diagrams only).

  • --watermark — opt-in visible "Powered by kUML" label in the bottom-right corner; the canvas grows downward so it structurally cannot overlap diagram content (added in v0.38.0). Independent of the always-on <!-- Generated by kUML vX.Y — kuml.dev -→ metadata comment, which is emitted on every render regardless of this flag.

If the script contains a umlModel { …​ } with multiple diagrams, each diagram renders to its own file using the diagram name as the file stem.

kuml render auto-detects the modelling language from the script’s return value — UML, SysML 2, C4, or BPMN (bpmnModel { …​ }). For BPMN models it also runs the BPMN constraint checker and prints any violations as warnings before writing the output.

kuml generate

Generate code from a script using a registered code generator.

kuml generate --input <script> [options]

Options:

  • -i, --input <script> — path to the *.kuml.kts script (classic mode). Repeat the option to merge several UML class scripts into one model first (same rules as kuml transform); the generator then runs once on the merged model. Several ERM scripts are not supported.

  • -o, --output <dir> — output directory (created if missing)

  • --plugin <name> — generator name (kotlin, java, sql, exposed, or custom)

  • --package <fqn> — target package (Java/Kotlin)

  • --options key=value,key=value — generator-specific options

Examples:

kuml generate --input model.kuml.kts --plugin java --package com.example --options java-style=records --output gen/
kuml generate --input model.kuml.kts --plugin sql --options sql-dialect=mysql,sql-drop=true --output gen/

--sql-migration: additive-only schema-diff migrations

A second mode diffs two ERM model snapshots and writes a single additive-only Flyway migration file — mutually exclusive with -i/--input:

kuml generate --sql-migration \
    --from schema-v1.kuml.kts \
    --to schema-v2.kuml.kts \
    --version 2 \
    --description add_orders \
    --output migrations/

Writes migrations/V2__add_orders.sql. Both scripts must be ERM models; any destructive or ambiguous change (dropped/renamed entity or column, type or primary-key change) makes generation refuse with the full list of blockers. See ERM DSL for details.

kuml validate

Validate expressions and structure. Exits non-zero on any violation.

kuml validate [options] <script>

Options:

  • -o, --output, --format text|json — output format (default: human-readable text)

  • --strict — also fail on any expression parse warning (guards, effects, parametric constraints)

  • --check-stereotypes — additionally validate stereotype applications (required properties, OCL constraints from profiles); off by default

  • --no-check-structure — skip structural checks (duplicate IDs, circular inheritance, dangling references)

  • --no-check-style — skip the named-argument source-style check

Output is structured: every violation prints constraint name, host classifier, OCL body, and a short failure message. Exit code 5 on violations, 0 on clean. Suitable as a CI step.

See Validation Reference for full flag details, exit codes, and a GitHub Actions integration example.

kuml diagnostics

Emit script compile/eval diagnostics with their source locations, for editor and IDE integration (this is what the JetBrains plugin’s inline error highlighting uses).

kuml diagnostics <script>

Unlike kuml validate — which focuses on OCL/structural model violations and prints script errors as a plain, location-less message — diagnostics preserves the line and column of every diagnostic so an editor can place squiggles precisely.

Output is one diagnostic per line on stdout, tab-separated (so consumers need no JSON parser):

<severity>	<startLine>	<startCol>	<endLine>	<endCol>	<message>
  • severity is WARNING, ERROR, or FATAL (only these are reported).

  • Location fields are empty when the diagnostic carries no location (e.g. a whole-file failure). The message is the last field, with any tab/newline replaced by a space, so split('\t') with a limit of 6 is always safe.

  • The command always exits 0 — validity is conveyed by the emitted lines, not the exit code, so callers can parse the result regardless of script validity.

Example — a script with two unresolved references:

$ kuml diagnostics broken.kuml.kts
ERROR	3	5	3	13	Unresolved reference 'nonsense'.
ERROR	3	18	3	19	Unresolved reference 'y'.

A valid script produces no output.

kuml simulate

Run a state-machine, activity or BPMN process simulation. See the simulate reference for the full event/trace format.

kuml simulate [options] <script> [<events>]

<events> is the JSON file with the event array; omit it with --interactive.

Options:

  • --interactive — REPL mode (no events file)

  • --out <path> — write the trace to a file (otherwise stdout)

  • --expected <path> — diff trace against an expected file; exit code 7 on mismatch

  • --epoch-clock — replace wall-clock timestamps with monotonic epoch ms from 0

  • --max-steps <n> — step limit for activity execution (default 1000)

  • --sandbox — run guards and effects in the sandbox; --guard-timeout-ms <n> sets the guard timeout (default 100)

  • --process <id> — BPMN process to execute when the model declares several

  • --max-tokens <n>, --time-budget-ms <n> — token-flow limits for BPMN and activity models (defaults 10000 and 30000)

  • --strict-guard-coverage — treat an exclusive/inclusive split with no matching guard and no default edge as an error

kuml transform

Model-to-model (M2M) and model-to-text transformation. Applies a named transformer to a kUML source script and writes the result into an output directory.

kuml transform [options] <script>...

Options:

  • -t, --transformer <id> — transformer ID (required unless --list-transformers is given)

  • --list-transformers — list all registered transformers and exit

  • -o, --output <dir> — output directory for the generated files

  • --from bpmn|uml-activity, --to uml-activity|bpmn — shorthand for the two BPMN bridge transformers

  • --package <name> — override the output package name (transformer-specific)

  • --options key=value,key=value — transformer context options, for example idType=uuid. --package is shorthand for package=; giving both with different values is a usage error.

  • --model-name <name> — name of the merged model (several scripts only, default merged)

  • --trace-out <file> — write the transform trace as JSON

Built-in transformers: uml-to-jpa, uml-to-rest (OpenAPI 3.0), uml-to-k8s, uml-to-docker, uml-to-erm, uml-to-erm-script, uml-to-exposed, uml-to-exposed-psm, uml-to-exposed-via-erm, erm-to-exposed, c4-to-uml, bpmn-to-uml-activity, uml-activity-to-bpmn, arxml-to-sysml2 and sysml2-to-arxml. Plugins can register more; --list-transformers prints the current set with descriptions.

Examples:

kuml transform --list-transformers domain.kuml.kts
kuml transform domain.kuml.kts --transformer uml-to-rest --output api/
kuml transform process.kuml.kts --from bpmn --to uml-activity --output out/

See SysML 2 DSL Reference for the SysML 2 transformer targets.

Multi-script models

Large models are often split across several scripts. A script that needs an entity owned by another script declares a minimal stub of it (at least the id) so that associations can point at it. Passing several scripts merges their UML class diagrams into one model, removes those stubs, and runs the transformer once:

kuml transform 00-members.kuml.kts 10-orders.kuml.kts 20-tags.kuml.kts \
    --transformer uml-to-exposed-via-erm --options idType=uuid --package com.example.db --output gen/

Merge rules:

  • Scripts are processed in sorted order of their canonical path, so the result does not depend on the order of the arguments.

  • Classes with an «Entity» stereotype and a non-blank tableName tag are grouped by that tag. The declaration with the most attributes is canonical; on a tie the first one in sorted script order wins.

  • Every other declaration of the group must only have attributes the canonical one also has. Otherwise the merge fails with exit code 18, naming the table, both classes, both scripts and the offending attributes. Nothing is written.

  • Classes without that tag and interfaces are de-duplicated by name (per kind) across scripts with the same rule: the declaration with the most members (attributes plus operations) is canonical, and every declaration from another script may only have members the canonical one has, otherwise exit code 18. Same-named declarations inside one script are left alone. This also applies to kuml generate with several -i scripts, so that a stub never overwrites the full declaration in the generated file.

  • Enumerations are de-duplicated by name: the declaration with the most literals is canonical, and every other declaration may only have literals the canonical one has. Otherwise the merge fails with exit code 18.

  • References to removed stubs (association ends, generalizations, realizations, dependencies) are redirected to the canonical class. Associations that become identical afterwards (same unordered pairs of (type, role) ends) are kept once. If such duplicates from different scripts differ in name, applied stereotypes (for example a foreign key with onDelete), multiplicity, navigability or aggregation, the merge fails with exit code 18 instead of silently picking one.

  • Output order: the elements of all scripts in sorted order (the canonical declaration keeps its own position), followed by all associations. The merged model is therefore equivalent to a single script that contains the same elements in this order without the stubs, and generates byte-identical output.

Multi-script mode accepts UML class diagrams only. A BPMN transformer, --from/--to, a C4 or ERM script, a repeated file or more than 1000 scripts is rejected. The transformer must consume UML class diagrams (for example uml-to-exposed-via-erm or uml-to-jpa); one that needs another input type, such as erm-to-exposed, is rejected with a usage error. With a single script the behaviour is unchanged.

kuml version

Print kUML version information.

kuml version [--json]

Options:

  • --json — emit version info as a single-line JSON object ({"version":"…","gitSha":"…","jdk":"…","buildTime":"…"})

Without flags, prints the same human-readable version string as kuml --version. Useful in CI to record the exact kUML version used for a build artefact.

kuml export

Export a kUML model to an external format.

kuml export --format structurizr|xmi|arxml|profile-uml [--output <path>] <script>

Options:

  • --format <name> — structurizr (Structurizr DSL), xmi (Eclipse EMF/UML2 XMI), arxml (AUTOSAR ARXML) or profile-uml (a KumlProfile as an Eclipse UML2 .profile.uml)

  • --output <path> — output file (default: the input name with the format’s extension)

xmi needs the JVM distribution (EMF is not part of a native-image build); a build without it exits with code 24. See EMF / XMI I/O, AUTOSAR / ARXML I/O and Structurizr export.

kuml import

Read an external format back into a *.kuml.kts script.

kuml import --format structurizr|xmi|arxml [--output <path>] <input>

Options:

  • --format <name> — structurizr (workspace .dsl), xmi (.xmi) or arxml (.arxml)

  • --output <path> — output *.kuml.kts file (default: the input name with a .kuml.kts extension)

kuml profile

Inspect registered profiles. Useful for debugging stereotype-driven codegen.

kuml profile list
kuml profile show JavaEE
kuml profile validate JavaEE       # self-check: every stereotype constraint is parseable

kuml reverse

Reverse-engineer Java or Kotlin source code, SQL DDL, or ARXML files into a *.kuml.kts script. Discovers reverse engines via ServiceLoader from kuml-codegen-reverse-java (V3.0.7) and kuml-codegen-reverse-kotlin (V3.0.8).

kuml reverse --list-engines                                # list registered engines
kuml reverse src/main/java   --lang java   --output domain.kuml.kts
kuml reverse src/main/kotlin --lang kotlin --output domain.kuml.kts
kuml reverse src/main/java   --lang auto                   # majority-vote on file extensions
kuml reverse src/main/kotlin --verbose-diagnostics         # print every INFO/WARN on stderr

Options:

  • --lang java|kotlin|auto — source language. Default: auto (file-extension majority, ≥ 60 % share required).

  • --output <file> — write the generated *.kuml.kts here; defaults to stdout.

  • --include "<glob>" (repeatable) — file include patterns. Defaults: **/*.java / **/*.kt per --lang. A glob matches if it matches the file name or the path relative to the source root (always compared with / separators; **/ also matches files directly in the root). Supported syntax: , *, ?, [abc], {a,b}. Matching is case-sensitive; a backslash is treated as a path separator, not as an escape.

  • --exclude "<glob>" (repeatable) — file exclude patterns, same matching as --include. Excludes always win over includes. Examples: --exclude "*Test.kt" (by file name), --exclude "**/test/**" (by path). Excluded files are not parsed and do not appear in the model; references to their types stay as plain type names.

  • --model-name <name> — name of the generated model (default ReverseEngineered).

  • --format source|arxml|sql — what to reverse: source code (default), ARXML import and merge, or SQL DDL to an ERM model.

  • --dialect <name> — SQL dialect for --format sql (default postgres).

  • --list-engines — print available reverse engines (id + description) and exit.

  • --verbose-diagnostics — print every WARN/INFO diagnostic on stderr (default: one-line summary).

--include/--exclude are currently applied by the Kotlin engine only. The Java engine still compares globs with the file name only (path globs such as **/test/** have no effect there). With --lang kotlin an include of exactly **/*.java (the Java default) is ignored.

The Kotlin engine is JVM-only (it bundles kotlin-compiler-embeddable), so the reverse subcommand is available in the Fat-JAR / installDist / distTar / runtimeZip distributions but excluded from the GraalVM Native Image build.

Diagnostic codes are grouped per engine:

  • REV-CORE-NNN — engine-agnostic

  • REV-J-NNN — Java engine

  • REV-K-NNN — Kotlin engine

See the kuml-codegen-reverse-api README for the full table.

kuml ai

Inspect and manage AI provider configuration, agent tool sets, benchmarks, pricing, compliance audit logs, and the API key vault:

kuml ai provider list                # configured LLM providers
kuml ai tools list                    # agent tool sets (including the MCP bridge)
kuml ai bench                         # benchmark provider latency/quality
kuml ai pricing                       # provider pricing tables
kuml ai audit                         # compliance audit log
kuml ai vault                         # API key vault (AES-256-GCM)

kuml ai is not the MCP server entry point — there is no mcp-stdio subcommand. The MCP server is the standalone kuml-mcp binary (module kuml-mcp, mainClass = dev.kuml.mcp.MainKt), started directly as /path/to/kuml-mcp/bin/kuml-mcp. It exposes 6 authoring tools (kuml.render/validate/list_elements/describe/generate/examples) and 5 Behaviour-Runtime tools (kuml.run.start/event/snapshot/patch/stop) — agents can query and drive a kUML model the same way they query a database. See Authoring MCP and Behaviour-Runtime MCP for the full tool reference.

kuml workspace

Inspect, validate and render OKF knowledge workspaces — directory trees of Markdown documents with type: frontmatter and ` ```kuml ` diagram blocks:

kuml workspace init [--name <name>] [--mode knowledge|engineering] [--output <dir>]
kuml workspace info <dir>
kuml workspace validate <dir> [--strict-vocabulary] [--document <path>]... [--evaluate] [--strict]
kuml workspace render <dir> [-f svg|png] [-o <dir>] [--document <path>]... [--strict] [--no-mirror]
kuml workspace convert <src> --to okf|kts [--force] [--output <dir>] [--strict]
kuml workspace export <dir> --format pdf [--kind handbook|per-document|diagrams] [-o <file-or-dir>] [--force] [--strict]

export writes the workspace as PDF (handbook, one PDF per document, or a diagram folio) and runs the workspace’s diagram scripts; see Workspace PDF export.

init scaffolds a new workspace into --output (default ./<slug> from --name); info, validate and render take the workspace root as a positional <dir>; convert (added in v0.38.0) takes a single .kuml.kts script or OKF Markdown note (or a directory of them) and wraps/unwraps it into the other format — a text-level operation, not a model re-serialization, since both formats share identical DSL text.

This is the canonical subcommand group for workspace-level operations — there are no top-level kuml validate/kuml render aliases for it. See Knowledge Workspaces for the .kuml-workspace.toml marker format, the full type: vocabulary, and the OKF-* finding codes, including the OKF-C-00x codes specific to convert.

kuml watch

Re-render a script every time it changes. Never exits on a script error (it prints the error and waits for the next save); stop it with Ctrl+C.

kuml watch [--output <path>] [--format svg|png] [--width <px>] <script>

kuml fmt

Format *.kuml.kts files in place.

kuml fmt [--check] [--canonical] <script>...
  • --check — do not modify anything; exit 6 if any file needs formatting (for CI).

  • --canonical — apply the canonical normal form used for deterministic model hashing (removes all blank lines and unifies line endings). Stricter than the default format; combine with --check to verify hash stability in CI.

kuml serve

Start the browser editor: a Ktor/Netty server with a CodeMirror 6 editor, a live SVG preview, theme and layout selection, and SVG / PNG / LaTeX download.

kuml serve [--port <n>] [--host <address>]

The frontend is bundled with the distribution and loads no script from a third-party CDN.

kuml markdown and kuml asciidoc

Pre-render ` ``kuml ` blocks (Markdown) or `[source,kuml] blocks and kuml::path[] macros (AsciiDoc) to diagrams.

kuml markdown -i <in.md> -o <out.md> [--mode inline|linked-svg|linked-png] [--assets-dir <dir>] [-w <px>]
kuml asciidoc -i <in.adoc> -o <out.adoc> [--mode ...] [--assets-dir <dir>] [-w <px>] [--with-source]
kuml asciidoc --input-dir <dir> --output-dir <dir> [--quiet]

--mode selects how diagrams are embedded: inline (SVG in the document), linked-svg or linked-png (files written to --assets-dir, default <output-dir>/assets). The directory form of kuml asciidoc mirrors a whole Antora module tree and copies other files unchanged; it is the pre-render step Antora needs, because Antora’s Node.js Asciidoctor cannot load the JVM extension. See Markdown and AsciiDoc & Antora.

kuml run

Run a state machine or activity with a live event adapter.

kuml run [--adapter stdin|mcp|batch|chain-evm] [options] <script>
Adapter Behaviour

stdin (default)

Interactive REPL; built-in snapshot, status and quit commands.

mcp

Local REST server (POST /run/event, GET /run/snapshot, POST /run/patch, POST /run/stop, GET /run/health); --port (0 = random free port).

batch

Replays --events <file.json>; writes the trace with --out.

chain-evm

Streams events from an EVM contract (--rpc, --contract, optional --from-block) after verifying the on-chain modelHash. See Chain Adapters.

Persistent sessions: --restore <snapshot.json> resumes from a snapshot, --snapshot-out <path> writes one when the session ends, and --migration reject|fingerprint|vertices chooses the compatibility policy (default fingerprint). Supports UML, SysML 2 STM and ACT.

kuml trace

Inspect, replay and export behaviour traces.

kuml trace replay [-v] [--events <file>] [--max-steps <n>] <tracefile> <script>
kuml trace export [--format otlp-json] [--service-name <name>] [-o <path>] <tracefile>

replay re-executes a recorded state-machine or activity trace against its source model and compares the result (exit 8 on a mismatch). export converts a trace to OpenTelemetry OTLP JSON.

kuml sandbox

kuml sandbox validate [--strict] [--guard-timeout-ms <n>] <script>

Statically checks guards and action bodies against the sandbox policy (exit 12 on violations). --strict uses the strict preset (short timeout, no built-ins, minimal limits).

kuml chain

Connect behaviour-runtime models to EVM contracts.

kuml chain connect --rpc <url> --contract <0x…>                       # print the on-chain model identity
kuml chain verify  --rpc <url> --contract <0x…> <model>               # local canonical hash vs. on-chain modelHash (exit 50 on mismatch)
kuml chain events  --rpc <url> --contract <0x…> [--from-block <n>] [--limit <n>]
kuml chain sign    --private-key "$KUML_SIGNING_KEY" [--out <file>] <model>   # EIP-712 signature (secp256k1)
kuml chain verify-sig [--sig <file>] [--expected-signer <address>] <model>

Pass the signing key through an environment variable as shown, so it never lands in your shell history.

See Chain Adapters for the full guide.

kuml plugin

Install and manage kUML plugins (Theme, Renderer, Layout, Codegen, Reverse).

kuml plugin list                          # installed plugins
kuml plugin search [query] [--category <c>] [--sort rating|downloads|name]
kuml plugin install [--force] <plugin.jar>
kuml plugin remove <id>
kuml plugin info <id>
kuml plugin permissions <id>              # declared permissions
kuml plugin check-updates                 # exit 44 if updates are available
kuml plugin upgrade [--all] [-y] [<id>]   # exit 45 if --all and one upgrade failed
kuml plugin reload                        # re-read plugins from disk (development)
kuml plugin init [<category>] [--id <id>] [--name <name>] [--output <dir>]

install verifies the plugin’s Ed25519 signature; --skip-signature-check exists only for local development JARs. Plugins that touch the file system must declare permissions, which install and upgrade ask you to confirm (-y accepts them). init scaffolds a starter project for one of the five categories (theme, renderer, layout, codegen, reverse); the template repository is kuml-dev/plugin-template. The registry is plugins.kuml.dev.

kuml update

Check GitHub for a newer release (kUML never updates itself).

kuml update check     # exit 0 = current, 10 = update available, 11 = pre-release only, 1 = offline
kuml update notes [--target <tag>] [--offline] [--no-cache]

kuml completion

kuml completion bash|zsh|fish

Prints a shell completion script, for example source <(kuml completion bash).

kuml dump-json

kuml dump-json --diagram-out <file> --layout-out <file> [--model-out <file>] <script>

Dumps the parsed diagram, its owning model and the computed layout as JSON. It is the input of the browser-hosted wasm playground render path; --model-out is required for C4, SysML 2, BPMN and Blueprint scripts.

Logging

All log output goes to stderr — stdout is reserved for rendered output (SVG/PNG) and structured JSON, so it is always safe to pipe (kuml render --format svg > out.svg) or redirect (kuml validate --output json 2>/dev/null) without a stray log line corrupting the result.

Set KUML_LOG_LEVEL to control verbosity (default WARN). Valid values are TRACE, DEBUG, INFO, WARN, ERROR, OFF and ALL (case-insensitive):

KUML_LOG_LEVEL=DEBUG kuml ai provider list

KUML_LOG_LEVEL can also be set as a JVM system property (-DKUML_LOG_LEVEL=DEBUG) instead of an OS environment variable — useful when launching the CLI from a wrapper script or a java -jar invocation that has no convenient way to export an env var. Both channels are normalized identically; a system property takes precedence over the environment variable if both are set, matching Logback’s own substitution lookup order.

An unset KUML_LOG_LEVEL falls back to WARN. A value outside the list above (a plausible-but-wrong guess like SILENT, NONE or quiet) is normalized back to WARN as well, rather than being passed through — Logback’s own parser would otherwise silently fall back to maximum verbosity (DEBUG) for any name it doesn’t recognize, which is the opposite of what a lower-verbosity guess like SILENT was going for. This normalization applies the same way regardless of which channel (environment variable or system property) the value was set through.

Third-party HTTP/AI client loggers (io.ktor, ai.koog, de.betchvaia, aws.smithy.kotlin, software.amazon.awssdk, org.eclipse.elk, org.apache.hc, io.netty) are intentionally pinned to WARN regardless of KUML_LOG_LEVEL — those stacks log full request/response bodies, including Authorization headers, at DEBUG/TRACE. Raising KUML_LOG_LEVEL only ever increases kUML’s own log verbosity.

Exit codes

Code Meaning

0

Success.

1

kuml update check could not reach GitHub.

2

Usage error (missing or invalid arguments).

3

Script error (compilation or model evaluation failed).

4

I/O error while reading input or writing output.

5

OCL constraint violations found (kuml validate).

6

kuml fmt --check found files that need formatting.

7

kuml simulate --expected produced a trace that differs from the goldfile.

8

kuml trace replay: the replayed trace differs from the recorded one.

9

kuml trace replay: unsupported trace flavour (activity traces).

10 / 11

kuml update check: a newer stable release / only a newer pre-release exists.

12 / 13

kuml sandbox validate found policy violations / a guard timed out in a sandboxed simulation.

14

kuml reverse --lang <id> referenced an unknown engine.

15

kuml reverse engine returned ERROR-level diagnostics.

16

kuml reverse found no source files in the given directory.

17

kuml reverse --format sql: the DDL could not be parsed.

18

kuml transform / kuml generate with several scripts: two declarations of the same entity (same «Entity».tableName), class, interface or enumeration, or two duplicate associations, cannot be merged. Nothing is written.

20 / 21

kuml run: the requested port is busy / --restore was rejected by the migration policy.

24

The requested import/export format is not available in this distribution (for example xmi in a native-image build).

26 / 27

kuml simulate of a BPMN process or activity: a token-flow limit was exceeded / the flow deadlocked.

40 – 45

kuml plugin: not found (40), incompatible version (41), permission denied (42), invalid signature (43), updates available (44), upgrade failed (45).

50 – 53

kuml chain / kuml run --adapter chain-evm: hash mismatch (50), connection error (51), invalid signature (52), signer mismatch (53).

60 / 61

kuml ai bench: a task failed / the provider is unreachable.

These codes are stable — CI scripts can branch on them.

Performance notes

The CLI compiles each script once and caches the result in the Kotlin scripting host. The first invocation is slow (cold JVM, JIT warmup, ELK initialisation) — typically 2-4 seconds. Subsequent invocations within the same JVM are sub-second.

For build pipelines that render dozens of diagrams, the Gradle plugin’s kumlRender task is much faster: it reuses the Gradle daemon’s warm JVM and Gradle’s incremental input checks skip unchanged files entirely.