{"record":{"id":"5384009ac9428855","repo":"docker/cli","slug":"cannot-merge-volumes-w","errorCode":null,"errorMessage":"cannot merge volumes: %w","messagePattern":"cannot merge volumes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/compose/loader/merge.go","lineNumber":39,"sourceCode":"\nfunc (s *specials) Transformer(t reflect.Type) func(dst, src reflect.Value) error {\n\tif fn, ok := s.m[t]; ok {\n\t\treturn fn\n\t}\n\treturn nil\n}\n\nfunc merge(configs []*types.Config) (*types.Config, error) {\n\tbase := configs[0]\n\tfor _, override := range configs[1:] {\n\t\tvar errs []error\n\t\tif services, err := mergeServices(base.Services, override.Services); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"cannot merge services: %w\", err))\n\t\t} else {\n\t\t\tbase.Services = services\n\t\t}\n\t\tif err := mergo.Map(&base.Volumes, &override.Volumes, mergo.WithOverride); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"cannot merge volumes: %w\", err))\n\t\t}\n\t\tif err := mergo.Map(&base.Networks, &override.Networks, mergo.WithOverride); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"cannot merge networks: %w\", err))\n\t\t}\n\t\tif err := mergo.Map(&base.Secrets, &override.Secrets, mergo.WithOverride); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"cannot merge secrets: %w\", err))\n\t\t}\n\t\tif err := mergo.Map(&base.Configs, &override.Configs, mergo.WithOverride); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"cannot merge configs: %w\", err))\n\t\t}\n\t\tif err := errors.Join(errs...); err != nil {\n\t\t\treturn nil, errors.Join(fmt.Errorf(\"failed to merge file %s\", override.Filename), err)\n\t\t}\n\t}\n\treturn base, nil\n}\n\nfunc mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, error) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/compose/loader/merge.go#L21-L57","documentation":"Thrown by merge() when mergo.Map fails merging the `Volumes` maps of two compose Configs. mergo.Map merges map[string]VolumeConfig by key; failure is rare and usually indicates a nil destination map or a non-mergeable value type introduced by an earlier transform bug.","triggerScenarios":"Merging two compose files where the Volumes map merge raises an error from mergo (e.g. nil map, type mismatch after a custom transform).","commonSituations":"Combining `-f` files where one defines volumes and the other overrides with incompatible shapes; programmatic Config construction leaving Volumes nil.","solutions":["Check the wrapped `%w` cause from mergo for the specific key/field.","Ensure both files define volumes with the same structural shape (driver/driver_opts/labels consistency).","Avoid overriding an external volume with a managed one across files."],"exampleFix":"// before\n# base.yml\nvolumes:\n  data:\n    driver: local\n# override.yml\nvolumes:\n  data:\n    external: true\n// after\n# pick one source mode per volume across all merged files\nvolumes:\n  data:\n    driver: local","handlingStrategy":"try-catch","validationCode":"// Ensure volumes with the same key are structurally compatible before merge.\nfunc validateMergeableVolumes(base, override map[string]types.VolumeConfig) error {\n    for k, ov := range override {\n        bv, ok := base[k]\n        if !ok {\n            continue\n        }\n        if bv.External.External != ov.External.External {\n            return fmt.Errorf(\"volume %s: external flag differs across files\", k)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Surface the wrapped mergo cause clearly.\nif err := cfg.Load(details); err != nil {\n    var me interface{ Unwrap() error }\n    if errors.As(err, &me) {\n        return fmt.Errorf(\"volume merge failed: %w\", me.Unwrap())\n    }\n    return err\n}","preventionTips":["Don't flip a volume between external and managed across override files.","Align driver/driver_opts/labels for shared volume keys.","Preview the merge with `docker compose config`."],"tags":["compose","merge","override","volume"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}