{"record":{"id":"4c142905a168998f","repo":"XTLS/Xray-core","slug":"existing-tag-found-tag-4c1429","errorCode":null,"errorMessage":"existing tag found: ${tag}","messagePattern":"existing tag found: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/proxyman/outbound/outbound.go","lineNumber":116,"sourceCode":"\t}\n\treturn nil\n}\n\n// AddHandler implements outbound.Manager.\nfunc (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tm.tagsCache = &sync.Map{}\n\n\tif m.defaultHandler == nil {\n\t\tm.defaultHandler = handler\n\t}\n\n\ttag := handler.Tag()\n\tif len(tag) > 0 {\n\t\tif _, found := m.taggedHandler[tag]; found {\n\t\t\treturn errors.New(\"existing tag found: \" + tag)\n\t\t}\n\t\tm.taggedHandler[tag] = handler\n\t} else {\n\t\tm.untaggedHandlers = append(m.untaggedHandlers, handler)\n\t}\n\n\tif m.running {\n\t\treturn handler.Start()\n\t}\n\n\treturn nil\n}\n\n// RemoveHandler implements outbound.Manager.\nfunc (m *Manager) RemoveHandler(ctx context.Context, tag string) error {\n\tif tag == \"\" {\n\t\treturn common.ErrNoClue\n\t}","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/proxyman/outbound/outbound.go#L98-L134","documentation":"Configuration/startup validation error from the outbound manager: addHandler refuses to register a second handler with the same non-empty tag. Tags are the lookup key for routing rules, balancers, and proxySettings chaining, so duplicates would make resolution ambiguous; the manager returns this error instead of overwriting.","triggerScenarios":"Calling Manager.addHandler (via outbound handler creation at instance start) with a handler whose Tag() is already a key in m.taggedHandler — i.e. two outbounds in the JSON config sharing the same \"tag\" string. Handlers with empty tags go to untaggedHandlers and never collide.","commonSituations":"Copy-pasting an outbound block and forgetting to change its tag; GUI clients (v2rayN-style) generating duplicated tags when importing profiles; merging configs that each define a common tag like 'proxy' or 'direct'. The instance fails to start with this error.","solutions":["Search the outbounds array for duplicate \"tag\" values and rename one of them to a unique string.","Update any references (routing rules, balancer selectors, proxySettings.tag) to the new name.","When merging configs, namespace tags with a prefix per profile (e.g. 'home-vless', 'office-trojan')."],"exampleFix":"// before\n[{ \"tag\": \"proxy\", \"protocol\": \"vless\", ... },\n { \"tag\": \"proxy\", \"protocol\": \"trojan\", ... }]\n\n// after\n[{ \"tag\": \"vless-out\", \"protocol\": \"vless\", ... },\n { \"tag\": \"trojan-out\", \"protocol\": \"trojan\", ... }]","handlingStrategy":"validation","validationCode":"// Pre-register check: unique, non-empty tags\nseen := map[string]bool{}\nfor _, ob := range cfg.Outbounds {\n    if ob.Tag == \"\" { continue }\n    if seen[ob.Tag] { return fmt.Errorf(\"duplicate outbound tag %q\", ob.Tag) }\n    seen[ob.Tag] = true\n}","typeGuard":"func validateUniqueTags(outbounds []OutboundConfig) error {\n    seen := map[string]struct{}\n    for _, o := range outbounds {\n        if o.Tag == \"\" { continue }\n        if _, dup := seen[o.Tag]; dup { return fmt.Errorf(\"duplicate tag %q\", o.Tag) }\n        seen[o.Tag] = struct{}{}\n    }\n    return nil\n}","tryCatchPattern":"// Registration-side: detect and report clearly at startup\nif err := ohm.AddHandler(ctx, h); err != nil {\n    if strings.Contains(err.Error(), \"existing tag found\") {\n        return fmt.Errorf(\"config: tag %q defined twice; rename one\", h.Tag())\n    }\n    return err\n}","preventionTips":["Namespace tags per profile when merging configs (home-, work-)","Add a config-lint step to CI for duplicate tags","Avoid empty tags unless you intentionally want untagged handlers"],"tags":["go","xray","config","outbound","duplicate"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}