grpc-ecosystem/grpc-gateway · error
components.%s.%s: %w
Error message
components.%s.%s: %w
What it means
Raised in mergeComponents when two inputs define the same components/* sub-map key and canonicalEqual fails to canonicalize either value. It wraps the underlying canonicalization/decode error with the component kind and key. The value's raw JSON could not be re-encoded for comparison, indicating malformed nested content.
Source
Thrown at openapiv3-merge/internal/merge/merge.go:352
{"requestBodies", &dst.RequestBodies, &src.RequestBodies},
{"headers", &dst.Headers, &src.Headers},
{"securitySchemes", &dst.SecuritySchemes, &src.SecuritySchemes},
{"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 {View on GitHub (pinned to a58a4436a3)
Solutions
- Validate both input files with a JSON parser to locate the malformed component value
- Fix or regenerate the document with the invalid component
- Ensure any tooling that post-processes the files preserves valid JSON
Defensive patterns
Strategy: validation
Validate before calling
func componentsAreValidJSON(data []byte) error {
var doc struct { Components map[string]map[string]json.RawMessage `json:"components"` }
if err := json.Unmarshal(data, &doc); err != nil { return err }
for kind, m := range doc.Components {
for k, v := range m {
var anyVal any
if err := json.Unmarshal(v, &anyVal); err != nil {
return fmt.Errorf("components.%s.%s: invalid JSON: %w", kind, k, err)
}
}
}
return nil
} Try / catch
for _, in := range inputs {
if err := componentsAreValidJSON(in.Data); err != nil {
return fmt.Errorf("%s: %w", in.Name, err)
}
}
merged, err := merge.Merge(inputs) Prevention
- Parse each input fully before merging to catch malformed component values
- Avoid post-processing generated JSON with string tools
- Validate components against the OpenAPI schema in CI
When it happens
Trigger: Calling Merge where two documents share a component key (e.g. components.schemas.example.v1.User) and the raw value of one is invalid JSON that only fails when canonicalized during the merge comparison.
Common situations: Corrupted generator output inside a component definition, hand-edits that broke nested JSON in a duplicated schema, or binary-encoding mishaps when embedding raw JSON.
Related errors
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/8f3326016b57e854.
Report an issue: GitHub.