argoproj/argo-workflows · error

failed to create %s: %w

Error message

failed to create %s: %w

What it means

saveParameter failed to create the destination file under /var/run/argo/outputs/parameters/ via os.Create after the directory was made. The parameter value cannot be written out for controller pickup. The wrapped OS error carries the concrete reason.

Source

Thrown at cmd/argoexec/commands/emissary.go:752

		logger.WithField("src", srcPath).WithError(err).Warn(ctx, "cannot save parameter, does not exist")
		return nil
	}
	if err != nil {
		return fmt.Errorf("failed to open %s: %w", srcPath, err)
	}
	defer func() { _ = src.Close() }()
	dstPath := varRunArgo + "/outputs/parameters/" + srcPath
	logger.WithFields(logging.Fields{
		"src": srcPath,
		"dst": dstPath,
	}).Info(ctx, "saving parameter")
	z := filepath.Dir(dstPath)
	if mkdirErr := os.MkdirAll(z, 0o755); mkdirErr != nil { // chmod rwxr-xr-x
		return fmt.Errorf("failed to create directory %s: %w", z, mkdirErr)
	}
	dst, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("failed to create %s: %w", srcPath, err)
	}
	defer func() { _ = dst.Close() }()
	if _, err = io.Copy(dst, src); err != nil {
		return fmt.Errorf("failed to copy %s to %s: %w", srcPath, dstPath, err)
	}
	if err = dst.Close(); err != nil {
		return fmt.Errorf("failed to close %s: %w", dstPath, err)
	}
	return nil
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check the wrapped error: EISDIR means the mirrored dstPath is a directory — use a distinct file path for the parameter.
  2. Raise RLIMIT_NOFILE / reduce concurrent outputs if EMFILE.
  3. Free disk space if ENOSPC.
  4. Fix /var/run/argo/outputs write permissions (volume + securityContext).
Defensive patterns

Strategy: try-catch

Validate before calling

// fd headroom + destination sanity check before saving outputs
var lim syscall.Rlimit
_ = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim)
if fi, err := os.Stat(dstPath); err == nil && fi.IsDir() {
    return fmt.Errorf("%s is a directory", dstPath)
}

Try / catch

err := runStep(ctx)
if err != nil && strings.Contains(err.Error(), "failed to create") {
    if errors.Is(errors.Unwrap(err), syscall.EISDIR) {
        return useDistinctParameterPath(ctx)
    }
    if errors.Is(errors.Unwrap(err), syscall.EMFILE) {
        return raiseNoFileAndRetry(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: os.Create(dstPath) fails: dstPath resolves to an existing directory, EMFILE (fd exhaustion), ENOSPC, or permission denied in the freshly created outputs directory.

Common situations: Nested parameter paths where dstPath already exists as a directory; many outputs saved concurrently hitting the fd limit; disk full; securityContext blocking writes.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/fa74aee514247d13. Report an issue: GitHub.