{"record":{"id":"b8e96aa618fb3a96","repo":"GoogleContainerTools/skaffold","slug":"deploy-read-manifest-err","errorCode":"DEPLOY_READ_MANIFEST_ERR","errorMessage":"unable to unmarshal Cloud Run Service config: %w","messagePattern":"unable to unmarshal Cloud Run Service config: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/deploy/cloudrun/deploy.go","lineNumber":216,"sourceCode":"\treturn d.monitor\n}\nfunc (d *Deployer) deployToCloudRun(ctx context.Context, out io.Writer, manifest []byte) error {\n\tcOptions := d.clientOptions\n\tif d.useGcpOptions {\n\t\tcOptions = append(cOptions, option.WithEndpoint(fmt.Sprintf(\"%s-run.googleapis.com\", d.Region)))\n\t\tcOptions = append(gcp.ClientOptions(ctx), cOptions...)\n\t}\n\tcrclient, err := run.NewService(ctx, cOptions...)\n\tif err != nil {\n\t\treturn sErrors.NewError(fmt.Errorf(\"unable to create Cloud Run Client\"), &proto.ActionableErr{\n\t\t\tMessage: err.Error(),\n\t\t\tErrCode: proto.StatusCode_DEPLOY_GET_CLOUD_RUN_CLIENT_ERR,\n\t\t})\n\t}\n\t// figure out which type we have:\n\tresource := &unstructured.Unstructured{}\n\tif err = k8syaml.Unmarshal(manifest, resource); err != nil {\n\t\treturn sErrors.NewError(fmt.Errorf(\"unable to unmarshal Cloud Run Service config: %w\", err), &proto.ActionableErr{\n\t\t\tMessage: err.Error(),\n\t\t\tErrCode: proto.StatusCode_DEPLOY_READ_MANIFEST_ERR,\n\t\t})\n\t}\n\tvar resName *RunResourceName\n\tswitch {\n\tcase resource.GetAPIVersion() == \"serving.knative.dev/v1\" && resource.GetKind() == \"Service\":\n\t\tresName, err = d.deployService(crclient, manifest, out)\n\t\t// the accessor only supports services. Jobs don't run by themselves so port forwarding doesn't make sense.\n\t\tif resName != nil {\n\t\t\td.accessor.AddResource(*resName)\n\t\t}\n\tcase resource.GetAPIVersion() == \"run.googleapis.com/v1\" && resource.GetKind() == \"Job\":\n\t\tresName, err = d.deployJob(crclient, manifest, out)\n\tcase resource.GetAPIVersion() == \"run.googleapis.com/v1\" && resource.GetKind() == \"WorkerPool\":\n\t\tresName, err = d.deployWorkerPool(crclient, manifest, out)\n\tdefault:\n\t\terr = sErrors.NewError(fmt.Errorf(\"unsupported Kind for Cloud Run Deployer: %s/%s\", resource.GetAPIVersion(), resource.GetKind()),","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/deploy/cloudrun/deploy.go#L198-L234","documentation":"Before deploying, `deployToCloudRun` parses the rendered manifest as a Kubernetes-style unstructured object to determine the Cloud Run resource kind. If `k8syaml.Unmarshal` fails on the manifest bytes, the error is wrapped as 'unable to unmarshal Cloud Run Service config: %w' with code DEPLOY_READ_MANIFEST_ERR.","triggerScenarios":"`k8syaml.Unmarshal(manifest, resource)` returns an error in `deployToCloudRun` — the rendered Cloud Run manifest (possibly from `skaffold render` output, multi-doc yaml, kustomize, or Helm) is not valid YAML or not parseable as an object.","commonSituations":"Hand-edited manifests with indentation/typo errors; a manifest containing multiple YAML documents where skaffold expects one; templates that render empty or non-object output; using a renderer (kustomize/helm) whose output includes non-Cloud-Run scaffolding.","solutions":["Validate the manifest with `skaffold render` and run the output through `kubectl apply --dry-run=client` or a YAML linter to find the syntax problem","Fix the YAML syntax error reported in the wrapped `%w` message (line/column are usually included)","Ensure each artifact renders a single Cloud Run manifest document (split multi-doc files)","If using kustomize/helm, fix templates that emit empty/invalid documents for this resource"],"exampleFix":"# before (manifest.yaml)\nservice:\n  metadata\n    name: broken   # missing colon\n# after\nservice:\n  metadata:\n    name: fixed","handlingStrategy":"validation","validationCode":"// Pre-validate rendered manifests before deploying\nfunc validateYAML(manifest []byte) error {\n\tvar obj map[string]interface{}\n\treturn yaml.Unmarshal(manifest, &obj)\n}\n// in CI: skaffold render | yamllint - && skaffold render | kubectl apply --dry-run=client -f -","typeGuard":null,"tryCatchPattern":"if err := deployer.Deploy(ctx, out, artifacts); err != nil {\n\tvar sErr *sErrors.Error\n\tif errors.As(err, &sErr) && sErr.Status().ErrCode == proto.StatusCode_DEPLOY_READ_MANIFEST_ERR {\n\t\treturn fmt.Errorf(\"manifest is not valid for Cloud Run (%s): run 'skaffold render' and lint the output\", sErr.Status().Message)\n\t}\n\treturn err\n}","preventionTips":["Lint rendered manifests (yamllint/kubeval) in CI before deploying","Keep each Cloud Run manifest to a single YAML document","Run `skaffold render` locally and inspect output after editing templates","Avoid hand-editing rendered manifests; edit sources and re-render"],"tags":["cloud-run","yaml","manifest","unmarshal"],"backgroundTag":"yaml-parse-error","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"}