required fields do not work on the function pattern
What version of CUE are you using (cue version)?
cue version v0.12.1
go version go1.24.2
-buildmode exe
-compiler gc
-trimpath true
DefaultGODEBUG asynctimerchan=1,gotestjsonbuildtext=1,gotypesalias=0,httpservecontentkeepheaders=1,multipathtcp=0,randseednop=0,rsa1024min=0,tls3des=1,tlsmlkem=0,winreadlinkvolume=0,winsymlink=0,x509keypairleaf=0,x509negativeserial=1,x509rsacrt=0,x509usepolicies=0
CGO_ENABLED 1
GOARCH amd64
GOOS darwin
GOAMD64 v1
cue.lang.version v0.12.0
Does this issue reproduce with the latest stable release?
Yes, assuming that version 0.12.1 is the latest such release at present.
What did you do?
Following along with discussion in the "CUE" Discord server's "general" channel, I wrote a "function"-style definition that uses strings.Join and mandates that its "in" field be present, attempting to assist @FiloSottile:
import "strings"
#disjuncts: {
in!: [...string]
out: strings.Join(in, "|")
}
x: (#disjuncts & {
in: ["foo", "bar"]
}).out
Now, this works fine when I supply an "in" field in my struct that I'm unifying with the #disjuncts definition. However, if I omit that "in" field, CUE proceeds using an empty list as the default value for the "in" field.
import "strings"
#disjuncts: {
in!: [...string]
out: strings.Join(in, "|")
}
x: (#disjuncts & {
}).out
What did you expect to see?
An error message noting that the "in" field is required, perhaps treating the top-level "x" field as incomplete.
What did you see instead?
cue export treats the #disjuncts definition's "in" field as if it were unified with an empty list, and proceeds to evaluate and export the result of calling strings.Join([], "|"), which is an empty string.
With @cuematthew we discussed that this seems to be because required fields being present seems to only be enforced on the data that is exported; because we select .out, the fact that in is not present seems to not result in a required field error.
I've lost track of the current status for this problem. Is it that we—collectively—know how this should work and what we want to do about it, but haven't yet had time to implement it, or are we still puzzling over how it should work?
I suspect this has just fallen off the radar a little; thanks for bumping it. I would be surprised if anyone argued this wasn't a bug; I guess this is likely to be about the point at which required fields are enforced, and that currently it can come too late, after the selector-prefix has been discarded.
Just noting that, at least to my reading (although I defer to @mpvl), this is closely related to https://github.com/cue-lang/cue/issues/3711#issuecomment-2628831918.
See also #4089
FYI, it is not just the function pattern.
#disjuncts: {
in!: [...string]
out: in
}
_foo: #disjuncts & {
}
x: _foo.out