[PATCH pve-common v2 1/1] fix #7077: Change JSON Schema attribute validation order

Arthur Bied-Charreton
2026-02-06T16:12:08Z

The JSON Schema validation first checks input against the registered
format function, then against the registered pattern, and only then
against {min,max}-length.

This causes length constraints to be poorly reported when they are
implicit in custom format verification code or regex patterns, which
results in generic format violation error messages instead of the
more specific length violation.

Change the validation order to check length constraints before anything
else. This is functionally equivalent, and comes with the UX advantage
of providing more precise error messages in a lot of cases.

Signed-off-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
---
src/PVE/JSONSchema.pm | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/PVE/JSONSchema.pm b/src/PVE/JSONSchema.pm
index 0c9bb82..531a52c 100644
--- a/src/PVE/JSONSchema.pm
+++ b/src/PVE/JSONSchema.pm
@@ -1463,31 +1463,31 @@ sub check_prop {

} else {

- if (my $format = $schema->{format}) {
- eval { check_format($format, $value, $path); };
- if ($@) {
- add_error($errors, $path, "invalid format - $@");
+ if (defined(my $max = $schema->{maxLength})) {
+ if (length($value) > $max) {
+ add_error($errors, $path, "value may only be $max characters long");
return;
}
}

- if (my $pattern = $schema->{pattern}) {
- if ($value !~ m/^$pattern$/) {
- add_error($errors, $path, "value does not match the regex pattern");
+ if (defined(my $min = $schema->{minLength})) {
+ if (length($value) < $min) {
+ add_error($errors, $path, "value must be at least $min characters long");
return;
}
}

- if (defined(my $max = $schema->{maxLength})) {
- if (length($value) > $max) {
- add_error($errors, $path, "value may only be $max characters long");
+ if (my $format = $schema->{format}) {
+ eval { check_format($format, $value, $path); };
+ if ($@) {
+ add_error($errors, $path, "invalid format - $@");
return;
}
}

- if (defined(my $min = $schema->{minLength})) {
- if (length($value) < $min) {
- add_error($errors, $path, "value must be at least $min characters long");
+ if (my $pattern = $schema->{pattern}) {
+ if ($value !~ m/^$pattern$/) {
+ add_error($errors, $path, "value does not match the regex pattern");
return;
}
}
--
2.47.3