grpc-ecosystem/grpc-gateway · error
components.%s.%q: %s redefines an entry with a different val
Error message
components.%s.%q: %s redefines an entry with a different value
What it means
Raised in mergeComponents when two inputs define the same-named component (e.g. components.schemas."example.v1.User") with canonically different values. The strict merger rejects conflicting redefinitions, naming the component kind, key, and the input file that redefined it.
Source
Thrown at openapiv3-merge/internal/merge/merge.go:355
{"links", &dst.Links, &src.Links},
{"callbacks", &dst.Callbacks, &src.Callbacks},
{"pathItems", &dst.PathItems, &src.PathItems},
}
for _, p := range pairs {
if len(*p.src) == 0 {
continue
}
if *p.dst == nil {
*p.dst = make(map[string]json.RawMessage, len(*p.src))
}
for k, v := range *p.src {
if prev, dup := (*p.dst)[k]; dup {
same, err := canonicalEqual(prev, v)
if err != nil {
return fmt.Errorf("components.%s.%s: %w", p.name, k, err)
}
if !same {
return fmt.Errorf("components.%s.%q: %s redefines an entry with a different value", p.name, k, srcName)
}
continue
}
(*p.dst)[k] = v
}
}
return nil
}
// mergeTags appends tags from src to out, deduplicating by `name`. Two tag
// entries sharing a name must declare identical metadata.
func mergeTags(out *document, seen map[string]json.RawMessage, src *document) error {
for _, raw := range src.Tags {
name, err := tagName(raw)
if err != nil {
return fmt.Errorf("%s: tags: %w", src.name, err)
}
if prev, ok := seen[name]; ok {View on GitHub (pinned to a58a4436a3)
Solutions
- Rename one of the conflicting components (e.g. fully-qualify proto names so they stay unique)
- Make both definitions identical if the duplication is unintentional
- Move the shared component into a single input that the others reference via $ref
- Align the source definitions (proto messages) so generated schemas match
Example fix
// before (b.json)
"schemas": { "example.v1.User": { ... different fields ... } }
// after (b.json)
"schemas": { "example.v2.User": { ... } } Defensive patterns
Strategy: validation
Validate before calling
func findDuplicateComponents(inputs []merge.Input) map[string][]string {
seen := map[string][]string{}
for _, in := range inputs {
var doc struct { Components map[string]map[string]json.RawMessage `json:"components"` }
if json.Unmarshal(in.Data, &doc) != nil { continue }
for kind, m := range doc.Components {
for k := range m { seen[kind+"."+k] = append(seen[kind+"."+k], in.Name) }
}
}
dups := map[string][]string{}
for k, v := range seen { if len(v) > 1 { dups[k] = v } }
return dups
} Try / catch
merged, err := merge.Merge(inputs)
if err != nil {
if strings.Contains(err.Error(), "components.") && strings.Contains(err.Error(), "redefines") {
// resolve the component name collision before retrying
}
return err
} Prevention
- Use fully-qualified component names (e.g. package.v1.Message) so cross-file collisions cannot happen
- Define shared types once in a common input and $ref them elsewhere
- Diff duplicate components when a collision is reported; align the sources
- Keep proto package naming conventions that guarantee unique message names
When it happens
Trigger: Calling Merge where two documents declare the same schema/response/parameter/etc. name with different definitions — e.g. two proto files defining the same message name with different fields, so generated schemas differ.
Common situations: Name collisions across proto packages after stripping qualifiers, one team updating a shared schema in their copy only, vendored specs redefining common types, or version-skewed generator outputs for the same type.
Related errors
- openapi: %s declares %q but %s declares %q
- %s.%q: %s redefines an entry with a different value
- components.%s.%s: %w
- tags[%q]: %w
- tags[%q]: %s redefines a tag with different metadata
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/6acfba69be75183f.
Report an issue: GitHub.