cmd/cue: vet doesn't mention missing required fields when some other constraint is violated
What version of CUE are you using (cue version)?
$ cue version 0.6.0 0.9.2 web playground
Does this issue reproduce with the latest stable release?
yes
What did you do?
I have the following rule and data with errors: (https://cuelang.org/play/?id=9-UGk18oQdV#w=function&i=cue&f=export&o=cue)
#rule:
level1: {
required_param1!: string
required_param2!: string
...
level2: {
required_param1!: string
required_param2!: number
// ...
}
}
data: {
level1: {
required_param1: "value1"
extra_param: "value3"
level2: {
required_param1: "value1"
extra_param: "value3"
}
}
} & #rule
What did you expect to see?
All the errors at once after executing cue vet:
data.level1.level2.extra_param: field not allowed:
-:6:19
-:20:19
-:23:5
data.level1.level2.required_param2: field is required but not present:
-:8:19
-:23:5
data.level1.required_param2: field is required but not present:
-:4:11
-:23:5
What did you see instead?
data.level1.level2.extra_param: field not allowed:
-:6:19
-:20:19
-:23:5
And as I uncomment "// ..." to eliminate this validation error, I can see other two errors.
This makes one run cue vet several times after corrections and get new errors after that.
Tho goal is to see all errors/mismatches at once.
This also affects cue vet when matchN is involved, using required fields as part of its checks:
! exec cue vet -c
cmp stderr expected
-- file.cue --
package p
#S: {
a?: int
b?: int
matchN(1, [{a!: _}, {b!: _}])
}
A: #S & {a: 1, b: 2}
B: #S & {}
-- expected --
A: invalid value {a:1,b:2} (does not satisfy matchN): 2 matched, expected 1:
./file.cue:6:1
./file.cue:6:8
./file.cue:8:4
B: invalid value {a?:int,b?:int} (does not satisfy matchN): 0 matched, expected 1:
./file.cue:6:1
./file.cue:6:8
./file.cue:9:4
Failure with CUE v0.13.0-alpha.4.0.20250514105820-c456d085e0c1:
> ! exec cue vet -c
[stderr]
A: invalid value {a:1,b:2} (does not satisfy matchN): 2 matched, expected 1:
./file.cue:6:2
./file.cue:6:9
./file.cue:8:4
[exit status 1]
> cmp stderr expected
diff stderr expected
--- stderr
+++ expected
@@ -1,4 +1,8 @@
A: invalid value {a:1,b:2} (does not satisfy matchN): 2 matched, expected 1:
- ./file.cue:6:2
- ./file.cue:6:9
+ ./file.cue:6:1
+ ./file.cue:6:8
./file.cue:8:4
+B: invalid value {a?:int,b?:int} (does not satisfy matchN): 0 matched, expected 1:
+ ./file.cue:6:1
+ ./file.cue:6:8
+ ./file.cue:9:4
FAIL: foo.txtar:2: stderr and expected differ
failed run
The reason behind this current behaviour is that cue vet works in phases:
- Load the arguments
- Parse the arguments
- Evaluate the arguments
Within each phase there are some errors that are fatal that prevent us moving to the next phase. And indeed within a given phase, especially phase 3, there are "sub phases". (the actual term "phase" is just something I am appropriating for this answer). That same limitation on "we can't progress" applies in those sub-phases too.
As we improve things in the new evaluator, evalv3, which will be the default for v0.13.0, we can look to improve this error experience, to "make as much progress as possible", reporting as many errors as possible.
This is closely related to a conversation I had with @cuematthew regarding the LSP.