{"record":{"id":"6f5d4b07f6f7c4d7","repo":"kubernetes/kops","slug":"marshaling-kops-channels-pod-w","errorCode":null,"errorMessage":"marshaling kops-channels pod: %w","messagePattern":"marshaling kops-channels pod: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/channels/model.go","lineNumber":74,"sourceCode":"\tLifecycle    fi.Lifecycle\n\tAssetBuilder *assets.AssetBuilder\n}\n\nvar _ fi.CloudupModelBuilder = &ChannelsBuilder{}\n\nfunc (b *ChannelsBuilder) Build(c *fi.CloudupModelBuilderContext) error {\n\tchannels, err := b.channelList()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpod, err := b.buildPod(channels)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"building kops-channels pod: %w\", err)\n\t}\n\tmanifest, err := k8scodecs.ToVersionedYaml(pod)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling kops-channels pod: %w\", err)\n\t}\n\n\tc.AddTask(&fitasks.ManagedFile{\n\t\tContents:  fi.NewBytesResource(manifest),\n\t\tLifecycle: b.Lifecycle,\n\t\tLocation:  new(channelsManifestPath),\n\t\tName:      new(\"manifests-channels-kops-channels\"),\n\t})\n\treturn nil\n}\n\n// channelList returns the bootstrap channel plus cluster.Spec.Addons. The bootstrap URL is\n// built via vfs path joining so toolbox_enroll's identity comparison stays byte-identical.\nfunc (b *ChannelsBuilder) channelList() ([]string, error) {\n\tconfigBase, err := vfs.Context.BuildVfsPath(b.Cluster.Spec.ConfigStore.Base)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing configStore.base %q: %w\", b.Cluster.Spec.ConfigStore.Base, err)\n\t}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/channels/model.go#L56-L92","documentation":"After the kops-channels pod object is built, k8scodecs.ToVersionedYaml serializes it to a versioned YAML manifest for the ManagedFile task. This error wraps a serialization failure — rare, and indicates the in-memory pod object could not be converted to a versioned API type.","triggerScenarios":"ToVersionedYaml fails on the constructed v1.Pod, e.g. the pod object contains fields that cannot round-trip through the targeted codec/version.","commonSituations":"Mixed kops/k8s.io/api library version skew during a custom build; a bug in a patched channels builder injecting invalid fields; vendored dependency drift after `go mod` changes.","solutions":["Run `make gomod` / `make kops` to ensure k8s.io/api and apimachinery versions are consistent","Check the wrapped inner error for the offending field and remove/fix it in custom builder code","Pin the k8s.io/api & codec dependency versions to those in kops go.mod"],"exampleFix":"// before: pod object with unmarshalable field\npod.Spec.Containers = append(pod.Spec.Containers, badContainer)\n// after: validate fields exist in the k8s API version being coded\npod.Spec.Containers = append(pod.Spec.Containers, validContainer)","handlingStrategy":"try-catch","validationCode":"if _, err := k8scodecs.ToVersionedYaml(pod); err != nil { return fmt.Errorf(\"channels pod not serializable: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err := buildChannels(); err != nil {\n\tif strings.Contains(err.Error(), \"marshaling kops-channels pod\") {\n\t\t// suspect dependency skew: check k8s.io/api versions\n\t}\n\treturn err\n}","preventionTips":["Run `make gomod` after changing dependencies to keep k8s.io/api/apimachinery consistent","Avoid injecting non-standard fields into generated pod objects","Pin vendored k8s library versions to those in kops go.mod"],"tags":["yaml","serialization","channels"],"backgroundTag":"manifest-serialization-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}