Language rules

WOML is XML-like, not XML

WOML uses familiar markup but preserves the body of <script> as raw JavaScript. Authors do not use CDATA and do not escape JavaScript operators:

WOML
<script>
  if (score < 0.8 && enabled) {
    return { accepted: true };
  }
  return { accepted: false };
</script>

Rules:

  • Do not add an XML declaration.
  • Element and attribute names are lowercase and case-sensitive.
  • Multiword names use kebab-case.
  • Attribute values must be quoted.
  • Duplicate, unknown, or misplaced attributes and elements are errors.
  • Comments use <!-- ... --> outside raw script/schema content.
  • The first literal </script> ends a script body, even if it appears inside a JavaScript string or comment. Construct that text in pieces if needed.
  • The first literal </schema> ends an inline schema body.

Identifiers

IdentityPatternExample
Workflow ID[a-z][a-z0-9]*(?:-[a-z0-9]+)*process-order
Trigger, step, parallel, choice, switch, fork, and approval ID[a-z][A-Za-z0-9]*calculateTotal
Fork branch IDJavaScript-safe ID, local to its forkinstagram
Module alias[a-z][A-Za-z0-9]* for JS/TS modules; kebab-style custom tag names for reusable WOML definitionspricing, calculate-discount

Trigger IDs are unique within the workflow. Executable and structural IDs share one workflow-wide namespace because they can participate in durable identity and context.steps output.

Durations and rates

Durations use a positive number and one unit:

Text
10ms  30s  5m  2h  7d

Bare numbers are invalid. A runtime-policy rate is a positive count, a slash, and a duration:

Text
100/1m

JSON values

Step results, trigger payloads, workflow-call payloads, context, cache values, and state values must be JSON-compatible: null, booleans, finite safe numbers, strings, arrays, and objects. undefined, functions, symbols, BigInt, circular values, clients, and class instances are not valid durable outputs.