{"record":{"id":"7b95d9013d0b9bf2","repo":"GoogleContainerTools/skaffold","slug":"resource-found-in-s-is-not-a-k8s-job-verify-the","errorCode":null,"errorMessage":"resource found in %s is not a k8s job, verify the manifest path is for a job resource","messagePattern":"resource found in (.+?) is not a k8s job, verify the manifest path is for a job resource","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/k8sjob/util.go","lineNumber":103,"sourceCode":"\tif len(resourceYAML) == 0 {\n\t\treturn nil, fmt.Errorf(\"empty file found at path: %s, verify that the manifest path is correct\", path)\n\t}\n\n\t// - obj is the API object (e.g., Job)\n\t// - groupVersionKind is a generic object that allows\n\t//   detecting the API type we are dealing with, for\n\t//   accurate type casting later.\n\tobj, groupVersionKind, err := decoder.Decode(\n\t\t[]byte(resourceYAML),\n\t\tnil,\n\t\tnil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Only process Jobs for now\n\tif groupVersionKind.Group != \"batch\" || groupVersionKind.Version != \"v1\" || groupVersionKind.Kind != \"Job\" {\n\t\treturn nil, fmt.Errorf(\"resource found in %s is not a k8s job, verify the manifest path is for a job resource\", path)\n\t}\n\n\tjob := obj.(*batchv1.Job)\n\tif job.Labels == nil {\n\t\tjob.Labels = map[string]string{}\n\t}\n\n\treturn job, nil\n}\n\nfunc GetGenericJob() *batchv1.Job {\n\treturn &batchv1.Job{\n\t\tTypeMeta: metav1.TypeMeta{\n\t\t\tKind:       \"Job\",\n\t\t\tAPIVersion: \"batch/v1\",\n\t\t},\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tLabels: map[string]string{},","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/k8sjob/util.go#L85-L121","documentation":"LoadFromPath decodes the manifest and inspects its group/version/kind; this error is thrown when the resource is valid YAML but is not a batch/v1 Job. The k8sjob package only processes Jobs, so any other kind (Pod, Deployment, CronJob, wrong API version) is rejected with an explicit hint to check the manifest path.","triggerScenarios":"LoadFromPath is given a manifest whose groupVersionKind is not exactly group=batch, version=v1, kind=Job — e.g. the file contains a Pod, a Deployment, a batch/v1beta1 CronJob, or a multi-doc file whose first doc is another kind.","commonSituations":"Pointing the k8s job logging config at the deployment manifest instead of the job manifest, using an old apiVersion like batch/v1beta1, or a manifest file that starts with a ConfigMap before the Job document.","solutions":["Open the file at the configured path and confirm the first/top-level resource is apiVersion: batch/v1 with kind: Job","Fix the manifest path in the config to point at the actual Job manifest","Update old manifests from batch/v1beta1 to batch/v1 for Job/CronJob kinds","If the file has multiple documents, split them so the Job is the resource loaded"],"exampleFix":"// before\napiVersion: batch/v1beta1\nkind: CronJob\n// after\napiVersion: batch/v1\nkind: Job","handlingStrategy":"validation","validationCode":"var meta metav1.TypeMeta\nif err := yaml.Unmarshal(b, &meta); err != nil {\n    return err\n}\nif meta.GroupVersionKind().Group != \"batch\" || meta.GroupVersionKind().Kind != \"Job\" {\n    return fmt.Errorf(\"%s: expected batch/v1 Job, got %s\", path, meta.GroupVersionKind())\n}","typeGuard":"func isBatchV1Job(gvk schema.GroupVersionKind) bool {\n    return gvk.Group == \"batch\" && gvk.Version == \"v1\" && gvk.Kind == \"Job\"\n}","tryCatchPattern":"job, err := k8sjob.LoadFromPath(path)\nif err != nil {\n    if strings.Contains(err.Error(), \"not a k8s job\") {\n        return fmt.Errorf(\"manifest %q must be a batch/v1 Job\", path)\n    }\n    return err\n}","preventionTips":["Keep Job manifests in dedicated files separate from other resources","Convert legacy batch/v1beta1 resources to batch/v1","Run `kubectl apply --dry-run=client -f <file>` to confirm the parsed kind before use","For multi-doc files, split documents so each file holds one Job"],"tags":["kubernetes","manifest","type-mismatch"],"backgroundTag":"wrong-resource-kind","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"}