{"record":{"id":"fcb1dd34dccf960c","repo":"docker/cli","slug":"1-s-2-s-1-s-external-name-and-1-s-name-co","errorCode":null,"errorMessage":"%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name","messagePattern":"%\\[1\\]s %\\[2\\]s: %\\[1\\]s\\.external\\.name and %\\[1\\]s\\.name conflict; only use %\\[1\\]s\\.name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/compose/loader/loader.go","lineNumber":656,"sourceCode":"\t\tobj, err := loadFileObjectConfig(name, \"config\", types.FileObjectConfig(config), details)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfigConfig := types.ConfigObjConfig(obj)\n\t\tconfigConfig.Extras = loadExtras(name, source)\n\t\tconfigs[name] = configConfig\n\t}\n\treturn configs, nil\n}\n\nfunc loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig, details types.ConfigDetails) (types.FileObjectConfig, error) {\n\t// if \"external: true\"\n\tswitch {\n\tcase obj.External.External:\n\t\t// handle deprecated external.name\n\t\tif obj.External.Name != \"\" {\n\t\t\tif obj.Name != \"\" {\n\t\t\t\treturn obj, fmt.Errorf(\"%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name\", objType, name)\n\t\t\t}\n\t\t\tif versions.GreaterThanOrEqualTo(details.Version, \"3.5\") {\n\t\t\t\tlogrus.Warnf(\"%[1]s %[2]s: %[1]s.external.name is deprecated in favor of %[1]s.name\", objType, name)\n\t\t\t}\n\t\t\tobj.Name = obj.External.Name\n\t\t\tobj.External.Name = \"\"\n\t\t} else if obj.Name == \"\" {\n\t\t\tobj.Name = name\n\t\t}\n\t\t// if not \"external: true\"\n\tcase obj.Driver != \"\":\n\t\tif obj.File != \"\" {\n\t\t\treturn obj, fmt.Errorf(\"%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver\", objType, name)\n\t\t}\n\tdefault:\n\t\tobj.File = absPath(details.WorkingDir, obj.File)\n\t}\n","sourceCodeStart":638,"sourceCodeEnd":674,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/compose/loader/loader.go#L638-L674","documentation":"Returned by loadFileObjectConfig for secrets and configs when `external: true` is set and both `external.name` (deprecated) and `name` are present. objType is interpolated as 'secret' or 'config'.","triggerScenarios":"A `secrets:` or `configs:` entry has `external: true` plus `external.name` and `name` both non-empty.","commonSituations":"Porting an old compose file using `external.name` to the modern `name` field and leaving both; CI override file sets `name` while base sets `external.name`.","solutions":["Remove the deprecated `external.name` and keep `name`.","Ensure only one of the two fields is set across all merged compose files."],"exampleFix":"# before\nsecrets:\n  token:\n    external:\n      name: prod-token\n    name: prod-token\n# after\nsecrets:\n  token:\n    external: true\n    name: prod-token","handlingStrategy":"validation","validationCode":"func validateFileObjectName(objType, name string, obj map[string]any) error {\n    ext, _ := obj[\"external\"]\n    var extName string\n    if em, ok := ext.(map[string]any); ok {\n        extName, _ = em[\"name\"].(string)\n    }\n    topName, _ := obj[\"name\"].(string)\n    if ext == true && extName != \"\" && topName != \"\" {\n        return fmt.Errorf(\"%s %s: set only one of external.name or name\", objType, name)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `name` for secrets/configs; drop `external.name`.","Keep external-name logic in a single file when merging.","Validate rendered output with `docker compose config`."],"tags":["compose","secret","config","external","conflict","deprecation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}