{"record":{"id":"aa5e7e2e4abd70eb","repo":"caddyserver/caddy","slug":"matcher-is-defined-more-than-once-s","errorCode":null,"errorMessage":"matcher is defined more than once: %s","messagePattern":"matcher is defined more than once: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/httptype.go","lineNumber":1678,"sourceCode":"\tfor _, ms := range matcherSets {\n\t\tmsEncoded, err := encodeMatcherSet(ms)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"server block %v: %v\", sblock.block.Keys, err)\n\t\t}\n\t\tmatcherSetsEnc = append(matcherSetsEnc, msEncoded)\n\t}\n\n\treturn matcherSetsEnc, nil\n}\n\nfunc parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.ModuleMap) error {\n\td.Next() // advance to the first token\n\n\t// this is the \"name\" for \"named matchers\"\n\tdefinitionName := d.Val()\n\n\tif _, ok := matchers[definitionName]; ok {\n\t\treturn fmt.Errorf(\"matcher is defined more than once: %s\", definitionName)\n\t}\n\tmatchers[definitionName] = make(caddy.ModuleMap)\n\n\t// given a matcher name and the tokens following it, parse\n\t// the tokens as a matcher module and record it\n\tmakeMatcher := func(matcherName string, tokens []caddyfile.Token) error {\n\t\t// create a new dispenser from the tokens\n\t\tdispenser := caddyfile.NewDispenser(tokens)\n\n\t\t// set the matcher name (without @) in the dispenser context so\n\t\t// that matcher modules can access it to use it as their name\n\t\t// (e.g. regexp matchers which use the name for capture groups)\n\t\tdispenser.SetContext(caddyfile.MatcherNameCtxKey, definitionName[1:])\n\n\t\tmod, err := caddy.GetModule(\"http.matchers.\" + matcherName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"getting matcher module '%s': %v\", matcherName, err)\n\t\t}","sourceCodeStart":1660,"sourceCodeEnd":1696,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/httptype.go#L1660-L1696","documentation":"parseMatcherDefinitions found that a named matcher with the same name is already present in the block's matcher map. Each `@name` definition must be unique within a server block; redefining one — even with identical content — is rejected.","triggerScenarios":"Two `@foo ...` declarations in the same site block, or importing a snippet that defines `@foo` into a block that already defines `@foo` (e.g. the snippet is imported twice, or the block duplicates it manually).","commonSituations":"Reusable snippets containing named matchers imported multiple times or alongside local definitions; merging configs that each defined the same matcher name; refactoring that leaves an old definition next to a new one.","solutions":["Rename one of the duplicate matchers and update its references","Delete the redundant definition","If a snippet defines the matcher, do not redefine it locally and import the snippet only once","If the snippet is imported twice, pass distinct matcher usage or restructure the snippet to take a matcher as an argument via {block}"],"exampleFix":"# before\n(m) {\n  @foo path /foo*\n}\nexample.com {\n  import m\n  @foo path /bar*   # duplicate @foo\n  respond @foo 200\n}\n# after\n(m) {\n  @foo path /foo*\n}\nexample.com {\n  import m\n  respond @foo 200\n}","handlingStrategy":"validation","validationCode":"# Reject duplicate matcher names per block during generation\nfor block in blocks:\n    names = [m.name for m in block.matcher_defs]\n    if len(names) != len(set(names)):\n        raise ConfigError('duplicate matcher: ' + str(dups(names)))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefix snippet matcher names (e.g. @snip_foo) to avoid collisions with local names","Import matcher-defining snippets at most once per block","Rename, never redefine, when refactoring matchers"],"tags":["caddy","caddyfile","matchers","duplicate","snippets"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}