Problem
Persisting a rendered workload configuration can remove existing required fields from a MiniService spec and permanently wedge reconciliation.
This was reproduced with NVCA 3.1.0 on a BYOC Kubernetes cluster. A Helm workload rendered an nvcf-workload-config ConfigMap containing StatusByWorkerReadiness: true. The chart itself rendered successfully, but the function never completed deployment.
Observed behavior
After NVCA persisted spec.workloadConfig, the live MiniService changed from a complete spec to one where fields including these were empty or absent:
spec:
namespace: ""
icmsRequestName: ""
The intended spec.workloadConfig field was also absent.
The MiniService remained in Installing, no workload objects were applied, and the reconciler repeatedly returned:
terminal error: miniservice <name> has no namespace
Deleting the function also left the empty function namespace behind because the invalid MiniService could not reconcile through normal cleanup.
Expected behavior
NVCA should persist only spec.workloadConfig while retaining every existing MiniService field. Reconciliation should then continue and apply the rendered workload objects.
Root cause
Two behaviors interact in this path:
pkg/apis/nvca/v1alpha1/miniservice_json.go defines custom JSON serialization for MiniServiceSpec, but its compatibility payload omits WorkloadConfig. The intended field is therefore not serialized or deserialized.
internal/miniservice/reconcile.go:saveWorkloadConfig constructs a partial MiniService, then patches it with server-side apply, force ownership, and managedByValue:
r.Client.Patch(ctx, base, client.Apply, client.ForceOwnership, client.FieldOwner(managedByValue))
The custom serializer emits zero values for required fields on that partial object while omitting workloadConfig. The same field manager also owns fields from the original MiniService apply. The result overwrites or prunes required fields such as spec.namespace and spec.icmsRequestName without persisting the intended config.
Suggested fix
Include WorkloadConfig in the MiniServiceSpec compatibility JSON representation, then patch the workload config with a merge patch based on a deep copy of the existing object. This updates only spec.workloadConfig without changing field ownership for the rest of the spec.
Add a regression test that starts with a complete MiniService, saves a non-empty workload config, reads the object back, and verifies that namespace, icmsRequestName, Helm configuration, and other existing spec fields are unchanged.
Problem
Persisting a rendered workload configuration can remove existing required fields from a
MiniServicespec and permanently wedge reconciliation.This was reproduced with NVCA 3.1.0 on a BYOC Kubernetes cluster. A Helm workload rendered an
nvcf-workload-configConfigMap containingStatusByWorkerReadiness: true. The chart itself rendered successfully, but the function never completed deployment.Observed behavior
After NVCA persisted
spec.workloadConfig, the liveMiniServicechanged from a complete spec to one where fields including these were empty or absent:The intended
spec.workloadConfigfield was also absent.The MiniService remained in
Installing, no workload objects were applied, and the reconciler repeatedly returned:Deleting the function also left the empty function namespace behind because the invalid MiniService could not reconcile through normal cleanup.
Expected behavior
NVCA should persist only
spec.workloadConfigwhile retaining every existing MiniService field. Reconciliation should then continue and apply the rendered workload objects.Root cause
Two behaviors interact in this path:
pkg/apis/nvca/v1alpha1/miniservice_json.godefines custom JSON serialization forMiniServiceSpec, but its compatibility payload omitsWorkloadConfig. The intended field is therefore not serialized or deserialized.internal/miniservice/reconcile.go:saveWorkloadConfigconstructs a partialMiniService, then patches it with server-side apply, force ownership, andmanagedByValue:The custom serializer emits zero values for required fields on that partial object while omitting
workloadConfig. The same field manager also owns fields from the original MiniService apply. The result overwrites or prunes required fields such asspec.namespaceandspec.icmsRequestNamewithout persisting the intended config.Suggested fix
Include
WorkloadConfigin theMiniServiceSpeccompatibility JSON representation, then patch the workload config with a merge patch based on a deep copy of the existing object. This updates onlyspec.workloadConfigwithout changing field ownership for the rest of the spec.Add a regression test that starts with a complete MiniService, saves a non-empty workload config, reads the object back, and verifies that
namespace,icmsRequestName, Helm configuration, and other existing spec fields are unchanged.