{"record":{"id":"2b3623e559fb7569","repo":"grpc-ecosystem/grpc-gateway","slug":"s-q-s-redefines-an-entry-with-a-different-valu","errorCode":null,"errorMessage":"%s.%q: %s redefines an entry with a different value","messagePattern":"(.+?)\\.%q: (.+?) redefines an entry with a different value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":312,"sourceCode":"\t\t\treturn nil, err\n\t\t}\n\t\tmergeExtras(out.extras, d.extras)\n\t}\n\treturn out, nil\n}\n\n// mergeOrdered appends entries from src into dst, rejecting key collisions\n// whose values differ canonically.\nfunc mergeOrdered(field string, dst, src *orderedObject, srcName string) error {\n\tfor _, k := range src.keys {\n\t\tv := src.vals[k]\n\t\tif existing, ok := dst.get(k); ok {\n\t\t\tsame, err := canonicalEqual(existing, v)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s.%s: %w\", field, k, err)\n\t\t\t}\n\t\t\tif !same {\n\t\t\t\treturn fmt.Errorf(\"%s.%q: %s redefines an entry with a different value\", field, k, srcName)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tdst.set(k, v)\n\t}\n\treturn nil\n}\n\n// mergeComponents unions each components/* sub-map. Same-named entries\n// across inputs must be canonically identical. The sub-maps are walked in\n// spec order so error messages are deterministic.\nfunc mergeComponents(dst, src *components, srcName string) error {\n\tpairs := []struct {\n\t\tname string\n\t\tdst  *map[string]json.RawMessage\n\t\tsrc  *map[string]json.RawMessage\n\t}{\n\t\t{\"schemas\", &dst.Schemas, &src.Schemas},","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L294-L330","documentation":"Raised in mergeOrdered when two inputs define the same key (e.g. the same URL path or webhook name) with canonically different values. The merger refuses to silently overwrite conflicting definitions, so it names the field, the key, and the input that caused the conflict.","triggerScenarios":"Calling Merge where docs A and B both define e.g. paths \"/users/{id}\" (or the same webhook key) with non-identical operation objects — the values differ even after key-order-insensitive canonicalization.","commonSituations":"Two proto packages accidentally mapping operations to the same route with different definitions, copy-pasted paths edited in one file but not the other, or a template that instantiates overlapping routes.","solutions":["Rename one of the conflicting paths/webhooks so each key is unique","Make the duplicate entries canonically identical if they are meant to be the same","Remove the redundant duplicate entry from the later input","Fix the generator configuration that maps two operations to the same route"],"exampleFix":"// before (b.json)\n\"/users/{id}\": { \"get\": { ... different ... } }\n// after (b.json)\n\"/users/{id}/v2\": { \"get\": { ... } }","handlingStrategy":"validation","validationCode":"func findDuplicatePaths(inputs []merge.Input) map[string][]string {\n\tseen := map[string][]string{}\n\tfor _, in := range inputs {\n\t\tvar doc struct { Paths map[string]json.RawMessage `json:\"paths\"` }\n\t\tif json.Unmarshal(in.Data, &doc) != nil { continue }\n\t\tfor k := range doc.Paths { seen[k] = append(seen[k], in.Name) }\n\t}\n\tdups := map[string][]string{}\n\tfor k, v := range seen { if len(v) > 1 { dups[k] = v } }\n\treturn dups\n}","typeGuard":null,"tryCatchPattern":"merged, err := merge.Merge(inputs)\nif err != nil {\n\tif strings.Contains(err.Error(), \"redefines an entry with a different value\") {\n\t\t// report conflicting route ownership to the owning teams\n\t}\n\treturn err\n}","preventionTips":["Ensure each route is generated by exactly one proto package/service","Deduplicate or rename overlapping paths before merging","Make repeated identical entries byte-identical (canonical) when duplication is intentional","Check route annotations/templates in generator configs for collisions"],"tags":["openapi","merge-conflict","paths"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}