docker/compose · error
cannot create output folder: %w
Error message
cannot create output folder: %w
What it means
When bridge.Convert is called with opts.Output set, it first removes any existing directory at that path (os.RemoveAll) and then recreates it with os.MkdirAll(out, 0o744). This error means the recreation failed for a reason other than the directory already existing — the %w wraps the mkdir error. Typical causes are a parent that is not writable, a path component that is a file, or read-only filesystems.
Source
Thrown at pkg/bridge/convert.go:76
return err
}
// for user to rely on compose.yaml attribute names, not go struct ones, we marshall back into YAML
raw, err := project.MarshalYAML(types.WithSecretContent)
// Marshall to YAML
if err != nil {
return fmt.Errorf("cannot render project into yaml: %w", err)
}
var model map[string]any
err = yaml.Unmarshal(raw, &model)
if err != nil {
return fmt.Errorf("cannot render project into yaml: %w", err)
}
if opts.Output != "" {
_ = os.RemoveAll(opts.Output)
err := os.MkdirAll(opts.Output, 0o744)
if err != nil && !os.IsExist(err) {
return fmt.Errorf("cannot create output folder: %w", err)
}
}
// Run Transformers images
return convert(ctx, dockerCli, model, opts)
}
func convert(ctx context.Context, dockerCli command.Cli, model map[string]any, opts ConvertOptions) error {
raw, err := yaml.Marshal(model)
if err != nil {
return err
}
dir, err := os.MkdirTemp("", "compose-convert-*")
if err != nil {
return err
}
defer func() {
err := os.RemoveAll(dir)View on GitHub (pinned to ddc4b044b6)
Solutions
- Check permissions on the parent directory and grant write access (chmod/chown) or choose a writable Output path
- Verify no regular file occupies the Output path or any parent component (ls -l on each segment)
- If Output is a bind mount, ensure it is mounted read-write
- Run the command with a fresh Output under a temp dir to confirm the rest of the conversion works
Example fix
# before $ docker compose ... --output /opt/results mkdir: permission denied # after $ sudo chown -R $(id -u) /opt/results # or $ docker compose ... --output ./results
Defensive patterns
Strategy: validation
Validate before calling
// Before Convert with Output set:
if opts.Output != "" {
if err := os.MkdirAll(opts.Output, 0o744); err != nil {
return fmt.Errorf("output path not writable: %w", err)
}
if info, err := os.Stat(opts.Output); err != nil || !info.IsDir() {
return fmt.Errorf("output path %s is not a writable directory", opts.Output)
}
} Prevention
- Pre-create the output directory in CI setup and assert writability with a touch-file
- Avoid paths on read-only mounts or under root-owned dirs when running as non-root
- Clean stale outputs before conversion in scripts
When it happens
Trigger: Calling bridge.Convert with Output pointing under a directory without write permission; Output whose parent path contains a regular file; Output on a read-only mount; a race where another process recreates the path as a file between RemoveAll and MkdirAll.
Common situations: CI containers running as a non-root user writing to /output or another root-owned path; converting to a path inside a read-only bind mount; a leftover file (not directory) at the Output path.
Related errors
- cannot create output folder: %w
- cannot take exclusive lock for project %q: %w
- stat %q: %w
- inspecting %q: %w
- walking %q: %w
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/d824a578ee54886e.
Report an issue: GitHub.