Draft
Mark slice reference fields nullable to survive reference-resolution clearing#2
Conversation
Copilot created this pull request from a session on behalf of
Breee
June 25, 2026 07:50
View session
Owner
Author
|
Fixed in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resources with a multi-reference selector (e.g.
compositeRolesSelector) fail reconciliation once the selector stops matching anything, after having matched previously:Root cause
crossplane-runtime's
APISimpleReferenceResolverpersists resolved references with a JSON merge patch (prepareJSONMerge→jsonpatch.CreateMergePatch). When resolution clears a slice field,omitemptydrops it from the resolved object, so the merge patch encodes the removal as an explicitnull. The generated CRD types these as non-nullable arrays, so the apply is rejected. Droppingomitemptysidesteps thenullbut produces empty arrays that drive a reconcile loop, so it isn't viable.Changes
kubebuildermarkers: add aNullable *booloption that emits the+nullablemarker (wired throughsetFrom/String). Note this is the field-only+nullablemarker that controller-gen actually recognizes —+kubebuilder:validation:Nullableis not registered by controller-tools and would be ignored.reference.go): generated slice…Refsfields now carry the nullable marker; single-valued…Selectorfields are left unchanged.field.go): a slice-typed field that has a reference (e.g.compositeRoles) is marked nullable in bothforProviderandinitProvider.Regenerated CRDs then accept the
nullthe merge patch produces:Notes
make generateagainst this branch) to pick up the nullable schema.