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

  1. Validate both input files with a JSON parser to locate the malformed component value
  2. Fix or regenerate the document with the invalid component
  3. 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

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.