grpc-ecosystem/grpc-gateway · error

%s.%s: %w

Error message

%s.%s: %w

What it means

Raised in mergeOrdered while unioning `paths` (or `webhooks`) when canonicalEqual fails to canonicalize a duplicate key's value. It wraps the underlying canonicalization/JSON decode error with the field and key. This means two inputs share the same key but the raw value could not be parsed for comparison (e.g. invalid JSON inside the value).

Source

Thrown at openapiv3-merge/internal/merge/merge.go:309

			return nil, err
		}
		if err := mergeSecurity(out, d); err != nil {
			return nil, err
		}
		mergeExtras(out.extras, d.extras)
	}
	return out, nil
}

// mergeOrdered appends entries from src into dst, rejecting key collisions
// whose values differ canonically.
func mergeOrdered(field string, dst, src *orderedObject, srcName string) error {
	for _, k := range src.keys {
		v := src.vals[k]
		if existing, ok := dst.get(k); ok {
			same, err := canonicalEqual(existing, v)
			if err != nil {
				return fmt.Errorf("%s.%s: %w", field, k, err)
			}
			if !same {
				return fmt.Errorf("%s.%q: %s redefines an entry with a different value", field, k, srcName)
			}
			continue
		}
		dst.set(k, v)
	}
	return nil
}

// mergeComponents unions each components/* sub-map. Same-named entries
// across inputs must be canonically identical. The sub-maps are walked in
// spec order so error messages are deterministic.
func mergeComponents(dst, src *components, srcName string) error {
	pairs := []struct {
		name string
		dst  *map[string]json.RawMessage

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Validate both input files fully with a JSON parser to find the malformed value
  2. Fix or regenerate the document containing the invalid path value
  3. Check for encoding corruption (BOM, truncated bytes) in the file
Defensive patterns

Strategy: validation

Validate before calling

func pathsAreValidJSON(data []byte) error {
	var doc struct { Paths map[string]json.RawMessage `json:"paths"` }
	if err := json.Unmarshal(data, &doc); err != nil { return err }
	for k, v := range doc.Paths {
		var anyVal any
		if err := json.Unmarshal(v, &anyVal); err != nil {
			return fmt.Errorf("paths.%s: invalid JSON: %w", k, err)
		}
	}
	return nil
}

Try / catch

for _, in := range inputs {
	if err := pathsAreValidJSON(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 define the same path key and canonicalize() hits a JSON decode error on either value — essentially malformed raw JSON captured during parse but not decoded until comparison.

Common situations: Malformed nested values produced by a broken generator, corrupted file bytes inside a path object, or hand-patched JSON with subtle syntax errors in duplicated entries.

Related errors


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/a86de4423553a46b. Report an issue: GitHub.