{"record":{"id":"9973d54d5ed1b672","repo":"docker/compose","slug":"cannot-create-output-folder-w-9973d5","errorCode":null,"errorMessage":"cannot create output folder: %w","messagePattern":"cannot create output folder: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bridge/transformers.go","lineNumber":59,"sourceCode":"}\n\nfunc CreateTransformer(ctx context.Context, dockerCli command.Cli, options CreateTransformerOptions) error {\n\tif options.From == \"\" {\n\t\toptions.From = DefaultTransformerImage\n\t}\n\tout, err := filepath.Abs(options.Dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif _, err := os.Stat(out); err == nil {\n\t\treturn fmt.Errorf(\"output folder %s already exists\", out)\n\t}\n\n\ttmpl := filepath.Join(out, \"templates\")\n\terr = os.MkdirAll(tmpl, 0o744)\n\tif err != nil && !os.IsExist(err) {\n\t\treturn fmt.Errorf(\"cannot create output folder: %w\", err)\n\t}\n\n\tif err := command.ValidateOutputPath(out); err != nil {\n\t\treturn err\n\t}\n\n\tcreated, err := dockerCli.Client().ContainerCreate(ctx, client.ContainerCreateOptions{\n\t\tImage: options.From,\n\t})\n\n\tdefer func() {\n\t\t_, _ = dockerCli.Client().ContainerRemove(context.Background(), created.ID, client.ContainerRemoveOptions{\n\t\t\tForce: true,\n\t\t})\n\t}()\n\n\tif err != nil {\n\t\treturn err","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/bridge/transformers.go#L41-L77","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Grant write permission on the destination parent: chmod u+w <parent> or run with appropriate privileges","Verify every component of Dest is a directory, not a file (ls -la on the path)","Pick a destination inside a known-writable location such as $HOME or a temp dir","On NFS/root_squash or read-only mounts, move Dest to a local writable path"],"exampleFix":"# before\n$ create-transformer --dest /srv/transformers/new\ncannot create output folder: mkdir /srv/transformers/new/templates: permission denied\n# after\n$ sudo install -d -o $(id -un) /srv/transformers\n$ create-transformer --dest /srv/transformers/new\n","handlingStrategy":"validation","validationCode":"// Before CreateTransformer, prove the parent is writable:\ndir := filepath.Dir(options.Dest)\nprobe := filepath.Join(dir, \".write-probe\")\nif err := os.WriteFile(probe, nil, 0o644); err != nil {\n\treturn fmt.Errorf(\"destination parent %s not writable: %w\", dir, err)\n}\n_ = os.Remove(probe)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Scaffold transformers into a scratch dir under $HOME or mktemp -d, then move into place","In containers/CI, run as a user with write access to mounted volumes","Check for files squatting on directory paths before running"],"tags":["filesystem","permissions","transformer","bridge"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}