Maestro YAML Parser Limitations in mobile-dev-inc/Maestro: 8 Strict Schema Constraints
Maestro's YAML parser enforces a rigid whitelist-based schema that only accepts predefined commands in a specific config-then-array structure, rejecting unknown commands, extra fields, anchors, aliases, and multi-document streams without modifying the source code.
The mobile-dev-inc/Maestro testing framework relies on a deliberately strict YAML parser that prioritizes validation over flexibility. Unlike general-purpose YAML parsers, Maestro's implementation accepts only a fixed vocabulary of commands and mandates a precise file structure. Understanding these Maestro YAML parser limitations is essential for writing valid flow files and troubleshooting configuration errors at the exact lines where validation fails.
Strict Command Whitelist and Schema Validation
Maestro's parser maintains two distinct registries for command validation in MaestroFlowParser.kt. The stringCommands map (lines 59‑75) defines commands that execute as simple scalars without parameters, while the objectCommands list (line 57) identifies commands that require an options object. Any command name not present in these collections triggers an immediate parsing error.
String Commands Cannot Carry Options
When the parser encounters a plain scalar command through parseStringCommand (lines 28‑34), it strictly validates that the command belongs to the stringCommands whitelist. If you attempt to write an objectCommand like launchApp as a plain scalar without its required options object, the parser throws "Missing Command Options" at the validation stage.
Object Commands Require Non-Null Options
Conversely, parseObjectCommand (lines 65‑73) mandates that every object-based command contains a non-null options object. A null value or missing configuration for commands defined in objectCommands results in "Incorrect Command Format". The parser further restricts command objects in lines 84‑100: after processing the command's options, it expects the end of the object, and any stray field causes "Invalid Command Format".
Mandatory File Structure Requirements
The parser enforces a rigid document structure through two critical validation points in MaestroFlowParser.kt. First, parseConfig (lines 95‑103) requires that every flow file begin with a START_OBJECT token representing the configuration section. If the file starts with an array or any other token, the parser immediately raises "Config Section Required".
Following the config section, parseCommands (lines 69‑86) expects a START_ARRAY token. The commands section must be a YAML array containing the sequence of test steps. Missing or malformed command lists result in "Commands Section Required", preventing any execution of improperly structured flows.
Limited Command Extensibility
Unlike extensible scripting engines, Maestro's parser only recognizes command types explicitly modeled as Kotlin data classes in YamlFluentCommand.kt. Each supported command—such as YamlLaunchApp, YamlScroll, or YamlTapOn—maps to a specific field structure in this file. The parser uses these data classes during Jackson deserialization, meaning new commands or custom extensions require direct modifications to the source code and recompilation of the framework.
Unsupported Standard YAML Features
The parser utilizes Jackson's ObjectMapper(YAMLFactory) with default settings and never enables extended features such as YamlParser.Feature.ALLOW_ALIAS. Consequently, standard YAML constructs including anchors (&), aliases (*), custom tags, and complex multi-document streams remain unsupported. This design choice ensures predictable parsing behavior but prevents users from leveraging YAML's advanced referencing capabilities to reduce repetition in flow files.
Error Handling and Validation Boundaries
Error surfacing occurs through FlowParseException.kt, which wraps parsing failures into user-facing messages. However, the parser's validation scope remains shallow: it checks command names against the whitelist and validates basic object structure through Jackson deserialization, but does not perform deep semantic validation of nested command fields beyond the initial type mapping.
Practical Examples of Parser Constraints
Valid Minimal Flow File
The following structure succeeds because it follows the required config-then-array pattern and uses only known commands:
appId: com.example.app # config section (required)
---
- launchApp # string command without options
- tapOn:
text: login
Missing Config Section
- launchApp
Result: Config Section Required (thrown at parseConfig, lines 95‑103).
Unknown Command
appId: com.example.app
---
- flyToMoon
Result: Invalid Command: flyToMoon (thrown in parseStringCommand, lines 38‑46).
Object Command Without Options
appId: com.example.app
---
- launchApp:
Result: Missing Command Options (thrown in parseStringCommand, lines 30‑34) because launchApp is listed in objectCommands.
Extra Field Inside Command
appId: com.example.app
---
- tapOn:
text: submit
unexpected: true
Result: Invalid Command Format: tapOn (thrown in parseObjectCommand, lines 84‑100) – the parser detects the extra top-level field unexpected.
Summary
- Whitelist enforcement: Only commands in
stringCommandsandobjectCommandsmaps withinMaestroFlowParser.ktare valid; all others raise immediate errors. - Structural rigidity: Flow files must start with a config object (parsed by
parseConfig) followed by a commands array (parsed byparseCommands). - Null safety: Object commands must contain non-null options objects; null values trigger "Incorrect Command Format".
- No extensibility: New commands require adding data classes to
YamlFluentCommand.ktand updating the parser registries. - Limited YAML feature support: Anchors, aliases, custom tags, and multi-document streams are disabled in the Jackson configuration.
- Strict field validation: Extra fields within command objects result in "Invalid Command Format" errors at
parseObjectCommandlines 84‑100.
Frequently Asked Questions
Can I use YAML anchors and aliases in Maestro flow files?
No. The parser uses Jackson's ObjectMapper(YAMLFactory) with default settings and explicitly does not enable YamlParser.Feature.ALLOW_ALIAS or similar options. According to the mobile-dev-inc/Maestro source code, anchors (&) and aliases (*) are not handled by the parser, and files containing these constructs will fail validation during the initial deserialization phase.
Why does Maestro reject my custom command names?
Maestro maintains a strict whitelist in MaestroFlowParser.kt where stringCommands (lines 59‑75) and objectCommands (line 57) define the only valid command strings. The parseStringCommand function (lines 38‑46) throws "Invalid Command" errors for any name not present in these registries. Adding custom commands requires modifying YamlFluentCommand.kt to define the new data class and updating the whitelist maps in the parser.
What happens if I omit the application configuration section?
The parser raises "Config Section Required" through parseConfig at lines 95‑103 of MaestroFlowParser.kt. This validation enforces that the first token in the YAML stream must be START_OBJECT (the config section). Flow files beginning directly with a commands array or any other structure fail immediately before command parsing begins.
Can I add optional parameters to existing Maestro commands through YAML alone?
No. The parser validates command structure against immutable Kotlin data classes in YamlFluentCommand.kt. While some commands accept optional fields defined in their data class, you cannot introduce new parameters or fields through YAML configuration alone. Attempting to add unrecognized fields results in "Invalid Command Format" errors from parseObjectCommand (lines 84‑100), as the parser rejects any object containing fields not explicitly modeled in the source code.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →