Validation
Before MPDEV builds anything it runs the package JSON through a deep validator. Errors fail the build immediately. Warnings let the build proceed but should be treated as TODOs – they catch real-world packaging mistakes that will bite you in production.
Validation happens in two stages:
- Schema validation (
mpdev-schema.json) – covers type, required-ness, enum membership, regex format, and length constraints. Fast and self-contained. - Package validators – richer checks that run after the schema pass: "does the file actually exist on disk?", "is this a real Azure Trusted Signing endpoint?", "is
key+nameunique across the registries array?", etc.
If any error is found, the build fails. Warnings let the build proceed.
2. CLI message format
Messages are produced in MSBuild diagnostic format so Visual Studio's Error List, GitHub Actions, and Azure Pipelines all parse them automatically.
Generic shape
mpdev: <severity>: <json-pointer> | <message>
Real example output
mpdev: info: Validating package...
mpdev: info: Package validation failed.
mpdev: warning: $.icon | Icon is not provided. Icon can be added as one of the following types - ".ico", ".png" or ".exe".
mpdev: warning: $.msix.shortcuts.0.location | It is not recommended to create a shortcut on the user's desktop as it is their private space.
mpdev: warning: $.msix.shortcuts.0.location | Shortcuts should be located in "C:\ProgramData\Microsoft\Windows\Start Menu\Programs".
mpdev: warning: $.registries.4.key | It is not recommended for applications to write registry in HKLM hive outside of "HKEY_LOCAL_MACHINE\SOFTWARE" and "HKEY_LOCAL_MACHINE\SYSTEM" keys.
mpdev: error: $.fileSystemEntries.0.sourcePath | Field is required.
mpdev: error: $.fileSystemEntries.2.sourcePath | File not found - "C:\My File.txt".
mpdev: error: $.registries.0.type | Invalid field value - "Foo". Valid values are - "String", "ExpandString", "Binary", "DWord", "MultiString", "QWord".
Severity levels
| Severity | Meaning |
|---|---|
info | Informational, never blocks. |
warning | Build proceeds, but address before release. |
error | Build fails. Must be fixed. |
3. How to read a message
Pick this real example:
mpdev: error: $.registries.0.type | Invalid field value - "Foo". Valid values are - "String", "ExpandString", "Binary", "DWord", "MultiString", "QWord".
| Token | Meaning |
|---|---|
mpdev: | The producing tool. |
error: | Severity. |
$.registries.0.type | The JSON pointer to the offending property. |
| Pipe ` | ` |
| Tail | Human-readable message + remediation hint. |
Reading the JSON pointer
| Token | Meaning |
|---|---|
$ | Root of the JSON document. |
.<name> | Property accessor. |
.0, .1, … | Zero-based array index. |
In the example above:
$– root.registries– theregistriesproperty.0– the first element of theregistriesarray.type– thetypeproperty within that element.
Open your JSON, navigate to that exact location, and fix it.
4. The validator catalog
Every named validator that can appear in a message, together with what it checks. (Source of truth: the Validators: blocks in mp-dev-2.2.0-json-schema.json.)
Universal
| Validator | Description |
|---|---|
required | Value must be provided and cannot be null. |
min | Value cannot be empty (string) or have fewer than N items (array). |
max | Value cannot exceed a max length (string) or item count (array). The specific maximum depends on the property. |
| illegal characters | Value does not contain illegal characters. The specific list depends on the property (e.g., services.name disallows / and \). |
| valid value | Value is one of an enum. The specific list depends on the property. |
Paths and files
| Validator | Description |
|---|---|
valid path | Syntactically valid file system path. Does NOT check disk existence. |
valid absolute path | Syntactically valid absolute path. Does NOT check disk existence. |
valid path on disk | Path exists on disk at build time. |
valid path in package | Path is a target path matching a file added via fileSystemEntries. |
valid file type | File path has a particular extension (e.g., .dll for customActions.dll.filePath). |
valid icon source | Path points to .ico, .png, .exe, or .dll. |
Strings, regexes, URLs
| Validator | Description |
|---|---|
valid regex | Value parses as a valid regex. |
valid http url | Value is a valid HTTP/HTTPS URL. |
valid timestamp server | Specific to $.digitalSignature.timestampServer – HTTP/HTTPS URL that responds with HTTP 200. |
valid distinguished names | Value is a valid Distinguished Name (RFC-1779). |
Versions and GUIDs
| Validator | Description |
|---|---|
valid version | Specific to $.(msi/msix).version – common/MSI version is Major.Minor.Build.Revision with Major > 0 (Revision optional). MSIX version is Major.Minor.Build.Revision with Major > 0. |
valid upgrade version | Major.Minor.Build, max 255 / 255 / 65535. |
valid upgrade code | Value is a valid GUID and not null/empty. |
unique upgrade code | $.msi.upgradeCode and every $.msi.secondaryUpgradeCodes.n.upgradeCode must be unique. |
Registry, services, signing
| Validator | Description |
|---|---|
valid registry key | Key starts with one of HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG. |
valid service start account | services.startAccount outside LocalSystem, LocalService, NetworkService is allowed only for MSI. |
valid start account password | services.msi.startAccountPassword cannot be set for built-in accounts. Use a custom startAccount instead. |
valid thumbprint | Specific to $.digitalSignature.thumbprint – matches a real, active certificate with a private key in the Personal store. |
valid publisher | Required when MSIX is built without a digital signature – publisher must follow Distinguished Name format. |
valid-azure-trusted-signing | When digitalSignature.signWith == 'AzureTrustedSigning', validates that MPDEV can connect to the Trusted Signing endpoint. |
Cross-section / uniqueness
| Validator | Description |
|---|---|
duplicate registry check | Entries in registries must be unique by key + name combination. |
unique custom action name | All name values across customActions.exe, .dll, .powershell are unique. |
unique url shortcut name | All urlShortcuts.name values are unique. |
unique name (MSIX dependencies) | msix.packageDependencies.n.name values are unique. |
Capability gates
| Validator | Description |
|---|---|
at least one msix shortcut required | Building MSIX requires at least one shortcuts entry. |
digital signature required - context menu | contextMenu for MSI requires digitalSignature to be configured. |
digital signature required - updater | msi.updater requires digitalSignature to be configured. |
valid install dir - updater | msi.updater requires installDir to be a sub-directory of %ProgramFiles% or %ProgramFiles(x86)%. |
valid custom action sequence | sequence must be StartOfExecution, EndOfExecution, or any short integer (-32768 to 32767). |
5. Suppressing message-format conversion
If you prefer plain output (e.g., for grep-style log parsing), turn off MSBuild format:
mpdev build package.json --use-msbuild-message-format false
Output then looks like:
Validating package...
Package validation failed.
warning: $.icon | Icon is not provided. ...
error: $.fileSystemEntries.0.sourcePath | Field is required.