{"record":{"id":"ddb04242f5196965","repo":"GoogleContainerTools/skaffold","slug":"custom-action-s-doesn-t-have-containers-custom-a","errorCode":null,"errorMessage":"custom action %s doesn't have containers. custom actions must have one or more containers associated","messagePattern":"custom action (.+?) doesn't have containers\\. custom actions must have one or more containers associated","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/schema/validation/validation.go","lineNumber":772,"sourceCode":"\n\t\tseenAcs[a.Name] = true\n\t}\n\n\treturn\n}\n\n// validateCustomActionsLists\n// - makes sure that each custom action has one or more containers\nfunc validateCustomActionsLists(runCtx *runcontext.RunContext) (errs []error) {\n\tacs := []latest.Action{}\n\n\tfor _, pipeline := range runCtx.GetPipelines() {\n\t\tacs = append(acs, pipeline.CustomActions...)\n\t}\n\n\tfor _, a := range acs {\n\t\tif len(a.Containers) == 0 {\n\t\t\terrs = append(errs, fmt.Errorf(\"custom action %s doesn't have containers. custom actions must have one or more containers associated\", a.Name))\n\t\t}\n\t}\n\treturn\n}\n\nfunc validateCustomActionsExecModes(runCtx *runcontext.RunContext) (errs []error) {\n\tacs := []latest.Action{}\n\n\tfor _, pipeline := range runCtx.GetPipelines() {\n\t\tacs = append(acs, pipeline.CustomActions...)\n\t}\n\n\tfor _, a := range acs {\n\t\tif a.ExecutionModeConfig.KubernetesClusterExecutionMode != nil && a.ExecutionModeConfig.LocalExecutionMode != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"custom action %s have more than one execution mode defined. custom actions must have only one execution mode\", a.Name))\n\t\t}\n\t}\n","sourceCodeStart":754,"sourceCodeEnd":790,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/schema/validation/validation.go#L754-L790","documentation":"Skaffold validates that every `customAction` declares at least one container, because a custom action has nothing to execute otherwise. validateCustomActionsLists iterates all pipelines' CustomActions and fails any action whose Containers list is empty or absent.","triggerScenarios":"Processing a skaffold.yaml where a `customActions:` entry omits the `containers:` field entirely or defines it as an empty list (`containers: []`).","commonSituations":"Creating a stub customAction entry before filling it in; deleting all containers while refactoring the action; a template or scaffold that emits an action shell with no contents.","solutions":["Add at least one container entry to the named customAction","Remove the empty customAction if it is not needed","Validate skaffold.yaml structure before running (e.g. `skaffold inspect` or schema lint)"],"exampleFix":"# before\ncustomActions:\n- name: smoke-test\n# after\ncustomActions:\n- name: smoke-test\n  containers:\n  - name: smoke\n    image: alpine\n    command: [\"sh\", \"-c\", \"echo ok\"]","handlingStrategy":"validation","validationCode":"func requireContainers(action CustomAction) error {\n\tif len(action.Containers) == 0 {\n\t\treturn fmt.Errorf(\"custom action %q has no containers\", action.Name)\n\t}\n\treturn nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Never commit customAction stubs without containers","Lint skaffold.yaml with the official JSON schema","CI check: fail if customActions entries lack containers"],"tags":["skaffold","yaml-validation","custom-actions","missing-field"],"backgroundTag":"schema-validation-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"}