{"record":{"id":"9e6ebe21506c03cc","repo":"docker/cli","slug":"failed-to-merge-file-s","errorCode":null,"errorMessage":"failed to merge file %s","messagePattern":"failed to merge file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/compose/loader/merge.go","lineNumber":51,"sourceCode":"\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) {\n\tmergeOpts := []func(*mergo.Config){\n\t\tmergo.WithAppendSlice,\n\t\tmergo.WithOverride,\n\t\tmergo.WithTransformers(&specials{m: map[reflect.Type]func(dst, src reflect.Value) error{\n\t\t\treflect.PointerTo(reflect.TypeFor[types.LoggingConfig]()):        safelyMerge(mergeLoggingConfig),\n\t\t\treflect.TypeFor[[]types.ServicePortConfig]():                     mergeSlice(toServicePortConfigsMap, toServicePortConfigsSlice),\n\t\t\treflect.TypeFor[[]types.ServiceSecretConfig]():                   mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),\n\t\t\treflect.TypeFor[[]types.ServiceConfigObjConfig]():                mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),\n\t\t\treflect.PointerTo(reflect.TypeFor[types.UlimitsConfig]()):        mergeUlimitsConfig,\n\t\t\treflect.TypeFor[[]types.ServiceVolumeConfig]():                   mergeSlice(toServiceVolumeConfigsMap, toServiceVolumeConfigsSlice),\n\t\t\treflect.TypeFor[types.ShellCommand]():                            mergeShellCommand,\n\t\t\treflect.PointerTo(reflect.TypeFor[types.ServiceNetworkConfig]()): mergeServiceNetworkConfig,","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/compose/loader/merge.go#L33-L69","documentation":"Top-level wrapper produced by the Compose merge loop at merge.go:51 when one or more sub-merges (services, volumes, networks, secrets, configs) for an override file failed. The underlying errors are collected with errors.Join and re-joined with this message naming the offending `override.Filename`. The real failures are in the joined chain; this message identifies WHICH file is at fault.","triggerScenarios":"Returned by `merge()` when at least one of the `errs` slice entries is non-nil after attempting to merge services, volumes, networks, secrets, or configs of an override into the base config. errors.Join(errs...) is non-nil (merge.go:50).","commonSituations":"An override Compose file (commonly docker-compose.override.yml) redefines a key with an incompatible type, or references structures the merge transformers cannot reconcile. The filename in the message points the developer at the offending file, while the wrapped errors identify the section.","solutions":["Read the wrapped error chain (use errors.Is / unwrap the joined errors) to see which section(s) failed (services, volumes, networks, secrets, configs).","Open the file named in the message and fix the incompatible structure flagged by the inner error.","Run `docker compose config` on each file separately to confirm each parses before merging.","Ensure override files only augment, not retype, keys present in the base file."],"exampleFix":"// diagnose the joined chain in Go\nif err != nil {\n    var joined interface{ Unwrap() []error }\n    if errors.As(err, &joined) {\n        for _, e := range joined.Unwrap() {\n            fmt.Println(e)\n        }\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Unwrap the joined chain to pinpoint the failing section.\nmerged, err := loader.merge(configs)\nif err != nil {\n    var multi interface{ Unwrap() []error }\n    if errors.As(err, &multi) {\n        for _, e := range multi.Unwrap() {\n            log.Println(\"merge sub-error:\", e)\n        }\n    }\n    return err\n}","preventionTips":["Run `docker compose config` on each file individually before merging.","Keep override files additive — never change a key's type.","Pin Compose file versions consistently across the project."],"tags":["compose","merge","multi-file","errors-join"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}