GoogleContainerTools/skaffold · error

custom action %s doesn't have containers. custom actions mus

Error message

custom action %s doesn't have containers. custom actions must have one or more containers associated

What it means

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.

Source

Thrown at pkg/skaffold/schema/validation/validation.go:772

		seenAcs[a.Name] = true
	}

	return
}

// validateCustomActionsLists
// - makes sure that each custom action has one or more containers
func validateCustomActionsLists(runCtx *runcontext.RunContext) (errs []error) {
	acs := []latest.Action{}

	for _, pipeline := range runCtx.GetPipelines() {
		acs = append(acs, pipeline.CustomActions...)
	}

	for _, a := range acs {
		if len(a.Containers) == 0 {
			errs = append(errs, fmt.Errorf("custom action %s doesn't have containers. custom actions must have one or more containers associated", a.Name))
		}
	}
	return
}

func validateCustomActionsExecModes(runCtx *runcontext.RunContext) (errs []error) {
	acs := []latest.Action{}

	for _, pipeline := range runCtx.GetPipelines() {
		acs = append(acs, pipeline.CustomActions...)
	}

	for _, a := range acs {
		if a.ExecutionModeConfig.KubernetesClusterExecutionMode != nil && a.ExecutionModeConfig.LocalExecutionMode != nil {
			errs = append(errs, fmt.Errorf("custom action %s have more than one execution mode defined. custom actions must have only one execution mode", a.Name))
		}
	}

View on GitHub (pinned to a1189de023)

Solutions

  1. Add at least one container entry to the named customAction
  2. Remove the empty customAction if it is not needed
  3. Validate skaffold.yaml structure before running (e.g. `skaffold inspect` or schema lint)

Example fix

# before
customActions:
- name: smoke-test
# after
customActions:
- name: smoke-test
  containers:
  - name: smoke
    image: alpine
    command: ["sh", "-c", "echo ok"]
Defensive patterns

Strategy: validation

Validate before calling

func requireContainers(action CustomAction) error {
	if len(action.Containers) == 0 {
		return fmt.Errorf("custom action %q has no containers", action.Name)
	}
	return nil
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Processing a skaffold.yaml where a `customActions:` entry omits the `containers:` field entirely or defines it as an empty list (`containers: []`).

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/ddb04242f5196965. Report an issue: GitHub.