Diagnostics
CradleXC reports diagnostics when it encounters problems while reading, validating or processing CRADLE source.
Diagnostics help identify where a scenario is malformed or where a referenced element does not match the surrounding scenario definition.
For syntax checking, use:
cxc validate -i <scenario.cradle>
For example:
cxc validate -i scenarios/HelloWorld.cradle
What diagnostics are for
Diagnostics can help identify problems such as:
- malformed CRADLE syntax
- invalid block structure
- missing separators or block terminators
- unresolved references
- inconsistent names
- unsupported properties
- invalid values
- compiler processing errors
The exact diagnostic format depends on the CradleXC release being used.
Validate first
When a scenario does not behave as expected, start with:
cxc validate -i <scenario.cradle>
For example:
cxc validate -i scenarios/HelloWorld.cradle
If validation reports an error, correct the source and run the command again.
A typical workflow is:
cxc validateSyntax errors
CRADLE blocks follow a defined structure.
For example:
instances() >
instance("Client"),
instance("Router").
Properties and references are separated with commas and the block ends with a period.
A malformed block such as:
instances() >
instance("Client")
instance("Router")
is missing:
- the comma between entries
- the terminating period
The corrected form is:
instances() >
instance("Client"),
instance("Router").
Missing block terminators
Every CRADLE block ends with:
.
For example:
metadata() >
name("ExampleEnvironment"),
eventType("sequence").
If the final period is missing, the block is incomplete.
Incorrect:
metadata() >
name("ExampleEnvironment"),
eventType("sequence")
Correct:
metadata() >
name("ExampleEnvironment"),
eventType("sequence").
Missing separators
Entries inside a block are separated by commas.
Incorrect:
instance("Client") >
os("ubuntu", "20.04")
object("InitializationScript").
Correct:
instance("Client") >
os("ubuntu", "20.04"),
object("InitializationScript").
Typed values
String values are double-quoted. Booleans, integers and durations use typed literals without quotes.
For example:
name("HelloWorld")
and:
os("ubuntu", "20.04")
Typed examples include needRoot(false) and pauseBeforeRun(5s).
Incorrectly quoted or unterminated values can cause parsing failures.
Incorrect:
name("HelloWorld)
Correct:
name("HelloWorld")
Unresolved instance references
Names connect declarations and definitions.
For example:
instances() >
instance("Client").
should correspond to:
instance("Client") >
os("ubuntu", "20.04").
If the definition uses another name:
instance("client") >
os("ubuntu", "20.04").
the reference is inconsistent.
Use matching spelling and capitalization:
instance("Client") >
os("ubuntu", "20.04").
Unresolved network references
A network declared as:
networks() >
network("lan_0").
should have a matching definition:
network("lan_0") >
endpoint("Client", "DHCP").
Avoid:
network("lan0") >
endpoint("Client", "DHCP").
if the declared name is lan_0.
Unresolved endpoint references
An endpoint should reference a declared instance.
For example:
network("lan_0") >
endpoint("Router", "DHCP").
requires a corresponding instance declaration such as:
instances() >
instance("Router").
If the instance does not exist, the endpoint reference cannot resolve correctly.
Unresolved object references
Objects can be referenced from metadata, instances and events.
For example:
metadata() >
object("InitializationScript").
with:
object("InitializationScript") >
location("${uriRemote}/scripts/initialize.sh").
and:
event("initialize_client") >
runObject("InitializationScript", "").
A mismatch such as:
runObject("InitScript", "")
references a different name.
Keep object names consistent throughout the scenario.
Unresolved event references
Events are declared within lifecycle phases.
For example:
mainEvent() >
event("initialize_client").
The corresponding event definition should exist:
event("initialize_client") >
instance("Client"),
needRoot(false),
subject("bash", ""),
runObject("InitializationScript", "").
If an event is referenced but never defined, review the event declaration and definition names.
Dependency references
dependsOn() references another semantic event name.
For example:
event("collect_evidence") >
dependsOn("initialize_client").
The referenced event should exist:
event("initialize_client") >
...
If the event identifier is misspelled or missing, the dependency does not resolve correctly.
Omit dependsOn() when an event has no explicit dependency.
Inspect the intermediate representation
When the source validates but the result is not what you expected, inspect the intermediate representation:
cxc dump-ir -i <scenario.cradle>
For example:
cxc dump-ir -i scenarios/HelloWorld.cradle
This can help you compare the authored source with the structure interpreted by CradleXC.
A useful diagnostic flow is:
cxc validatecxc dump-ircxc compilecxc dump-ir is optional during normal use.
Inspect compiled output
After validation succeeds, compile the scenario:
cxc compile \
-i <scenario.cradle> \
-o <output.yml>
For example:
cxc compile \
-i scenarios/HelloWorld.cradle \
-o HelloWorld.yml
Inspecting the generated YAML can help determine whether the scenario was interpreted as expected.
See Inspect Output for the full inspection workflow.
Grammar, compiler and schema differences
CRADLE currently has several related sources of language behavior:
| Source | Role |
|---|---|
| Grammar | Defines valid structural syntax. |
| CradleXC | Recognizes supported properties and processes their values. |
| JSON Schema | Describes the expected structured representation. |
These sources are not completely aligned.
As a result, a scenario can expose differences between:
- grammar validation
- compiler defaults
- compiler extensions
- schema-required properties
- schema value representations
Examples documented in the current language reference include:
eventTypeis required by the schema while CradleXC can default it tosequence- instance architecture
- network subnet handling differs between the schema and compiler
- endpoint addressing can default to
DHCP repositoryLocalis recognized as a compiler extensionconfig,descriptionandheuristicinclude compiler-specific behavior- event dependencies use
dependsOn()references
Do not treat grammar validation, compiler processing and JSON Schema validation as identical checks.
Unsupported or unexpected properties
The grammar can recognize the general shape of a property:
exampleProperty("value")
without the grammar itself determining whether the property is meaningful in the surrounding block.
CradleXC performs additional processing when interpreting the scenario.
If a property is not behaving as expected:
- confirm that the property is documented for that CRADLE element
- confirm the expected argument count
- confirm the expected values
- check whether it is a compiler extension
- validate against the CradleXC release being used
Defaults can affect output
CradleXC currently supplies defaults for some properties.
Documented examples include:
| Property | Current default behavior |
|---|---|
eventType | sequence when omitted |
| Endpoint address | DHCP when omitted |
needRoot | false when omitted |
pauseBeforeRun | 0 when omitted |
pauseAfterRun | 0 when omitted |
If compiled output contains a value that was not explicitly written in the source, check whether CradleXC supplied a documented default.
Backend-related diagnostics
A CRADLE scenario can validate successfully while backend-specific generation still fails.
This is because validation and backend generation are separate stages.
The workflow is:
A backend can have its own:
- feature limitations
- configuration requirements
- dependencies
- provider requirements
- diagnostics
For backend-related problems, see Use a Backend and Troubleshooting.
Recommended diagnostic workflow
When a scenario produces an error or unexpected output:
- Run
cxc validate. - Correct any syntax problems.
- Check named references for spelling and capitalization.
- Inspect compiler defaults and extensions relevant to the scenario.
- Use
cxc dump-irif the interpreted structure needs further inspection. - Compile the scenario and inspect the generated YAML.
- If the problem occurs only during target-specific generation, investigate the selected backend separately.
The corresponding commands are:
cxc validate -i scenarios/HelloWorld.cradle
cxc dump-ir -i scenarios/HelloWorld.cradle
cxc compile \
-i scenarios/HelloWorld.cradle \
-o HelloWorld.yml
Common checks
Before investigating a more complex problem, confirm that:
- every block ends with a period
- entries inside blocks are comma-separated
- property values are correctly quoted
- instance declarations have matching definitions
- network declarations have matching definitions
- endpoint names match declared instances
- object declarations have matching definitions
runObject()references match declared objects- events belong to lifecycle phases
- event references are unique and consistent
- dependency references resolve
- repository values are valid for the intended environment
- compiler extensions are supported by the CradleXC release being used
Report a problem
If a problem cannot be resolved, collect enough information to reproduce it.
Useful information includes:
- CradleXC version
- the command used
- complete diagnostic output
- the relevant
.cradlesource - compiled output where relevant
- backend name and version where relevant
- operating system and environment information
Check the CradleXC version with:
cxc --version
For environment-related issues, also include:
cxc doctor
Review diagnostic output and scenario files before sharing them. Remove credentials, tokens and other sensitive information that is not required to reproduce the issue.