GoogleContainerTools/skaffold · error
SKAFFOLD_CMDLINE is invalid: %w
Error message
SKAFFOLD_CMDLINE is invalid: %w
What it means
When skaffold is invoked with no CLI args (len(os.Args)==1) and the SKAFFOLD_CMDLINE env var is set (used by phases like deploy/build to propagate the original command line to a re-executed binary), Run() attempts to shell-split that value. If shell.Split fails (unbalanced quotes, malformed escaping), the error is wrapped as `SKAFFOLD_CMDLINE is invalid`.
Source
Thrown at cmd/skaffold/app/skaffold.go:45
shell "github.com/kballard/go-shellquote"
"github.com/GoogleContainerTools/skaffold/v2/cmd/skaffold/app/cmd"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output/log"
)
func Run(out, stderr io.Writer) error {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGINT, syscall.SIGPIPE)
defer cancel()
catchStackdumpRequests()
c := cmd.NewSkaffoldCommand(out, stderr)
if cmdLine := os.Getenv("SKAFFOLD_CMDLINE"); cmdLine != "" && len(os.Args) == 1 {
parsed, err := shell.Split(cmdLine)
if err != nil {
return fmt.Errorf("SKAFFOLD_CMDLINE is invalid: %w", err)
}
// XXX logged before logrus.SetLevel is called in NewSkaffoldCommand's PersistentPreRunE
log.Entry(ctx).Debugf("Retrieving command line from SKAFFOLD_CMDLINE: %q", parsed)
c.SetArgs(parsed)
}
c, err := c.ExecuteContextC(ctx)
if err != nil {
err = extractInvalidUsageError(err)
if errors.Is(err, context.Canceled) {
log.Entry(ctx).Debugln("ignore error since context is cancelled:", err)
} else if !cmd.ShouldSuppressErrorReporting(c) {
// As we allow some color setup using CLI flags for the main run, we can't run SetupColors()
// for the entire skaffold run here. It's possible SetupColors() was never called, so call it again
// before we print an error to get the right coloring.
errOut := output.SetupColors(context.Background(), stderr, output.DefaultColorCode, false)
output.Red.Fprintln(errOut, err)
}
}View on GitHub (pinned to a1189de023)
Solutions
- Unset SKAFFOLD_CMDLINE (`unset SKAFFOLD_CMDLINE`) when invoking skaffold manually.
- Fix quoting in the value so it parses as shell tokens (balanced quotes/escapes).
- Run skaffold with explicit arguments instead of relying on the env var (len(os.Args)>1 skips this path).
Example fix
// before export SKAFFOLD_CMDLINE='run --profile "dev'; skaffold // after unset SKAFFOLD_CMDLINE; skaffold run --profile dev
Defensive patterns
Strategy: try-catch
Validate before calling
if v, ok := os.LookupEnv("SKAFFOLD_CMDLINE"); ok && v != "" {
if _, err := shell.Split(v); err != nil {
os.Unsetenv("SKAFFOLD_CMDLINE")
}
} Try / catch
if err := runSkaffold(); err != nil {
if strings.Contains(err.Error(), "SKAFFOLD_CMDLINE is invalid") {
os.Unsetenv("SKAFFOLD_CMDLINE")
err = runSkaffold()
}
} Prevention
- Unset SKAFFOLD_CMDLINE when invoking skaffold interactively or in CI wrappers.
- Never hand-write the env var; let skaffold set it.
- Always pass explicit CLI arguments so the env-var path is skipped.
When it happens
Trigger: Invoking the skaffold binary with zero arguments while SKAFFOLD_CMDLINE contains a string shell.Split cannot parse — e.g. dangling quote `skaffold run --tag "`, unbalanced parentheses, or manual export of a corrupted value.
Common situations: Manually exporting SKAFFOLD_CMDLINE in a shell/CI to test behavior; a parent skaffold process serializing a command line containing characters shell.Split rejects; wrapper scripts clobbering the env var.
Related errors
- `apply` requires at least one manifest argument
- `exec` requires exactly one action to execute
- `config-dependencies add` requires exactly one file path arg
- `jobManifestPaths modify` requires exactly one manifest file
- `inspect namespaces list` requires exactly one manifest file
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/1a3fc4af370836fe.
Report an issue: GitHub.