{"record":{"id":"0b8e2ebfbdfd3de0","repo":"kubernetes/kops","slug":"unable-to-parse-assets-as-assetbuilder-is-not-defi","errorCode":null,"errorMessage":"unable to parse assets as assetBuilder is not defined","messagePattern":"unable to parse assets as assetBuilder is not defined","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/context.go","lineNumber":139,"sourceCode":"\t\tbaseIPInt := big.NewInt(0)\n\t\tbaseIPInt.SetBytes(ip6)\n\t\tserviceIPInt := big.NewInt(0)\n\t\tserviceIPInt.Add(big.NewInt(int64(id)), baseIPInt)\n\t\tserviceIP := make(net.IP, len(ip6))\n\t\tserviceIPBytes := serviceIPInt.Bytes()\n\t\tfor i := range serviceIPBytes {\n\t\t\tserviceIP[len(serviceIP)-len(serviceIPBytes)+i] = serviceIPBytes[i]\n\t\t}\n\t\treturn serviceIP, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"unexpected IP address type for ServiceClusterIPRange: %s\", networkingSpec.ServiceClusterIPRange)\n}\n\n// Image returns the docker image name for the specified component\nfunc Image(component string, clusterSpec *kops.ClusterSpec, assetsBuilder *assets.AssetBuilder) (string, error) {\n\tif assetsBuilder == nil {\n\t\treturn \"\", fmt.Errorf(\"unable to parse assets as assetBuilder is not defined\")\n\t}\n\n\tkubernetesVersion, err := kopsmodel.ParseKubernetesVersion(clusterSpec.KubernetesVersion)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\timageName := component\n\n\tif !kubernetesVersion.IsBaseURL() {\n\t\timage := \"registry.k8s.io/\" + imageName + \":\" + \"v\" + kubernetesVersion.String()\n\n\t\treturn assetsBuilder.RemapImage(image), nil\n\t}\n\n\t// The simple name is valid when pulling.  But if we\n\t// are loading from a tarfile then the image is tagged with\n\t// the architecture suffix.","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/context.go#L121-L157","documentation":"Image() builds the docker image reference for a kOps component, but resolving an image may require rewriting/verifying assets, which needs an AssetBuilder. The function guards against a nil assetsBuilder and refuses to run, returning this error instead of panicking on a nil pointer.","triggerScenarios":"Calling components.Image(component, clusterSpec, nil) — e.g. when a caller such as BuildOptions skips asset construction or a test passes no builder — and the component image cannot be resolved without the builder.","commonSituations":"Custom code or tests invoking Image() directly without building assets via assetutils/build options; refactored call sites that dropped the AssetBuilder argument; partial initialization of build options.","solutions":["Pass a valid *assets.AssetBuilder (e.g. built via BuildOptions / assetutils.RecommendAssets) instead of nil","If assets are irrelevant for your case, compute the image name manually or use the default image path that does not require asset rewriting","In tests, construct a minimal AssetBuilder or use the existing TestImage harness that supplies one"],"exampleFix":"// before\nimg, err := components.Image(\"kube-apiserver\", clusterSpec, nil)\n// after\nassetsBuilder := assets.NewAssetBuilder(assetsLocation, kubernetesVersion, false)\nimg, err := components.Image(\"kube-apiserver\", clusterSpec, assetsBuilder)","handlingStrategy":"validation","validationCode":"if assetsBuilder == nil {\n    return fmt.Errorf(\"assetsBuilder must be constructed before calling components.Image\")\n}","typeGuard":"func hasAssetBuilder(b *assets.AssetBuilder) bool { return b != nil }","tryCatchPattern":"img, err := components.Image(component, clusterSpec, assetsBuilder)\nif err != nil {\n    return fmt.Errorf(\"resolving image for %s: %w\", component, err)\n}","preventionTips":["Always obtain the AssetBuilder from BuildOptions rather than constructing ad-hoc","Add nil checks at call sites that receive a builder from upstream code","Keep tests using the existing harness that supplies a builder"],"tags":["go","nil-pointer","assets","validation"],"backgroundTag":"nil-argument-not-allowed","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"}