{"record":{"id":"5e16890732a8f0f1","repo":"GoogleContainerTools/skaffold","slug":"unmarshaling-config-w","errorCode":null,"errorMessage":"unmarshaling config: %w","messagePattern":"unmarshaling config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/kubernetes/manifest/filter.go","lineNumber":40,"sourceCode":"\t\"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\tk8syaml \"sigs.k8s.io/yaml\"\n)\n\n// Filter returns the manifest list that match any of the given `GroupKindSelector` items\nfunc (l *ManifestList) Filter(selectors ...GroupKindSelector) (ManifestList, error) {\n\tif l == nil {\n\t\treturn nil, nil\n\t}\n\tvar filtered ManifestList\n\tfor _, yByte := range *l {\n\t\t// Convert yaml byte config to unstructured.Unstructured\n\t\tjByte, err := k8syaml.YAMLToJSON(yByte)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"yaml to json error: %w\", err)\n\t\t}\n\t\tvar obj unstructured.Unstructured\n\t\tif err := obj.UnmarshalJSON(jByte); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unmarshaling config: %w\", err)\n\t\t}\n\t\tgvk := obj.GroupVersionKind()\n\t\tfor _, w := range selectors {\n\t\t\tif w.Matches(gvk.Group, gvk.Kind) {\n\t\t\t\tfiltered.Append(yByte)\n\t\t\t}\n\t\t}\n\t}\n\treturn filtered, nil\n}\n\n// SelectResources returns the resources defined in the manifest list that match any of the given `GroupKindSelector` items\nfunc (l *ManifestList) SelectResources(selectors ...GroupKindSelector) ([]unstructured.Unstructured, error) {\n\tif l == nil {\n\t\treturn nil, nil\n\t}\n\tvar customResources []unstructured.Unstructured\n\tfor _, yByte := range *l {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/kubernetes/manifest/filter.go#L22-L58","documentation":"After YAML→JSON conversion succeeds, Filter unmarshals each document into an unstructured.Unstructured object. UnmarshalJSON fails if the JSON is not a valid Kubernetes object (e.g. top-level JSON is not an object/mapping). The error is wrapped as 'unmarshaling config'.","triggerScenarios":"Calling ManifestList.Filter where a manifest converts to JSON that is not an object — e.g. the YAML document is a scalar or list, or the YAMLToJSON output is structurally invalid for unstructured decoding.","commonSituations":"A YAML file that is just a list of resources instead of individual documents, a manifest starting with '---' producing an empty document, or pipeline steps that append non-manifest text to the manifest stream.","solutions":["Ensure every YAML document is a mapping (starts with 'apiVersion:'/'kind:'), not a bare list or scalar","Split list-style YAML (kind: List) into separate documents or use the List kind properly","Remove empty documents / stray '---' separators that yield empty JSON","Check upstream render output for concatenated non-manifest content"],"exampleFix":"// before: file is a YAML list of resources\n- apiVersion: v1\n  kind: Service\n- apiVersion: v1\n  kind: Deployment\n// after: use a List document or one object per file\napiVersion: v1\nkind: List\nitems:\n- apiVersion: v1\n  kind: Service\n- apiVersion: v1\n  kind: Deployment","handlingStrategy":"validation","validationCode":"func isMappingDoc(doc []byte) bool {\n  var v interface{}\n  if err := yaml.Unmarshal(doc, &v); err != nil { return false }\n  _, ok := v.(map[string]interface{})\n  return ok\n}\n// reject documents where !isMappingDoc(m) before calling Filter","typeGuard":"func isK8sObject(m map[string]interface{}) bool {\n  _, hasKind := m[\"kind\"]\n  _, hasAPIVersion := m[\"apiVersion\"]\n  return hasKind && hasAPIVersion\n}","tryCatchPattern":"if _, err := manifests.Selectors(sel).Filter(...); err != nil {\n  if strings.Contains(err.Error(), \"unmarshaling config\") {\n    // dump the offending document for inspection and fail fast\n    return fmt.Errorf(\"non-object manifest document: %w\", err)\n  }\n  return err\n}","preventionTips":["Ensure every YAML document is an object with apiVersion/kind","Avoid stray '---' separators that create empty documents","Convert kind: List bundles into individual documents when a per-object pipeline is expected","Dry-run manifests with kubectl before integration into skaffold pipelines"],"tags":["kubernetes","manifest","unmarshal"],"backgroundTag":"manifest-unmarshal-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}