docker/compose · error

cannot create output folder: %w

Error message

cannot create output folder: %w

What it means

Inside bridge.CreateTransformer, after confirming the destination does not exist, the templates subdirectory is created via os.MkdirAll(filepath.Join(out, "templates"), 0o744). This error wraps a mkdir failure other than 'already exists' — in practice a permission problem or a path component that is a regular file. Note the pre-existence check on the parent makes normal duplicate runs surface as error 126 instead, so this path is specifically an OS-level failure.

Source

Thrown at pkg/bridge/transformers.go:59

}

func CreateTransformer(ctx context.Context, dockerCli command.Cli, options CreateTransformerOptions) error {
	if options.From == "" {
		options.From = DefaultTransformerImage
	}
	out, err := filepath.Abs(options.Dest)
	if err != nil {
		return err
	}

	if _, err := os.Stat(out); err == nil {
		return fmt.Errorf("output folder %s already exists", out)
	}

	tmpl := filepath.Join(out, "templates")
	err = os.MkdirAll(tmpl, 0o744)
	if err != nil && !os.IsExist(err) {
		return fmt.Errorf("cannot create output folder: %w", err)
	}

	if err := command.ValidateOutputPath(out); err != nil {
		return err
	}

	created, err := dockerCli.Client().ContainerCreate(ctx, client.ContainerCreateOptions{
		Image: options.From,
	})

	defer func() {
		_, _ = dockerCli.Client().ContainerRemove(context.Background(), created.ID, client.ContainerRemoveOptions{
			Force: true,
		})
	}()

	if err != nil {
		return err

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Grant write permission on the destination parent: chmod u+w <parent> or run with appropriate privileges
  2. Verify every component of Dest is a directory, not a file (ls -la on the path)
  3. Pick a destination inside a known-writable location such as $HOME or a temp dir
  4. On NFS/root_squash or read-only mounts, move Dest to a local writable path

Example fix

# before
$ create-transformer --dest /srv/transformers/new
cannot create output folder: mkdir /srv/transformers/new/templates: permission denied
# after
$ sudo install -d -o $(id -un) /srv/transformers
$ create-transformer --dest /srv/transformers/new
Defensive patterns

Strategy: validation

Validate before calling

// Before CreateTransformer, prove the parent is writable:
dir := filepath.Dir(options.Dest)
probe := filepath.Join(dir, ".write-probe")
if err := os.WriteFile(probe, nil, 0o644); err != nil {
	return fmt.Errorf("destination parent %s not writable: %w", dir, err)
}
_ = os.Remove(probe)

Prevention

When it happens

Trigger: Dest parent exists but is not writable by the current user; a file (not directory) sits where a path component must be created; SELinux/AppArmor denies mkdir; destination on a read-only filesystem.

Common situations: Running the transformer scaffolding as non-root into a root-owned directory; containerized runs with restrictive volume permissions; odd filesystems (NFS with root_squash, read-only bind mounts).

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/9973d54d5ed1b672. Report an issue: GitHub.