grpc-ecosystem/grpc-gateway · error

invalid tag entry: %w

Error message

invalid tag entry: %w

What it means

tagName parses a raw top-level `tags` entry to extract its `name`; if the entry is not valid JSON object data decodable into {name}, the parse failure is wrapped as `invalid tag entry: ...`. This happens before mergeTags can deduplicate, so the offending document's tags array contains an entry that is not a well-formed JSON object.

Source

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

		return raw, nil
	}
	var v any
	dec := json.NewDecoder(bytes.NewReader(raw))
	dec.UseNumber()
	if err := dec.Decode(&v); err != nil {
		return nil, err
	}
	return json.Marshal(v)
}

// tagName extracts the `name` field from a tag entry. Tag entries without
// a name violate the OpenAPI spec and are rejected.
func tagName(raw json.RawMessage) (string, error) {
	var t struct {
		Name string `json:"name"`
	}
	if err := json.Unmarshal(raw, &t); err != nil {
		return "", fmt.Errorf("invalid tag entry: %w", err)
	}
	if t.Name == "" {
		return "", errors.New("tag entry missing required \"name\"")
	}
	return t.Name, nil
}

// isJSONNull reports whether raw is the JSON null literal (possibly
// surrounded by whitespace). Empty input also counts as null.
func isJSONNull(raw json.RawMessage) bool {
	if len(raw) == 0 {
		return true
	}
	return bytes.Equal(bytes.TrimSpace(raw), []byte("null"))
}

// orderedObject is an insertion-ordered JSON object. It is used for
// `paths`, `webhooks`, and the bucket of unrecognised top-level keys —

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Locate the malformed tags entry in the failing input file and fix its JSON syntax
  2. Validate the whole input document with `jq . file.json` before merging
  3. Regenerate the spec from its source generator
  4. Run each input through a JSON Schema/OpenAPI validator to catch structural issues early

Example fix

// before: {"tags":[{"name":"pets"},{"name":"store",}]}
// after:  {"tags":[{"name":"pets"},{"name":"store"}]}
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range files {
    b, err := os.ReadFile(f)
    if err != nil { return err }
    var doc struct {
        Tags []json.RawMessage `json:"tags"`
    }
    if err := json.Unmarshal(b, &doc); err != nil { return err }
    for i, t := range doc.Tags {
        var tag struct{ Name string `json:"name"` }
        if err := json.Unmarshal(t, &tag); err != nil {
            return fmt.Errorf("%s: tags[%d]: %w", f, i, err)
        }
    }
}

Type guard

func isDecodableTagEntry(raw json.RawMessage) bool {
    var t struct{ Name string `json:"name"` }
    return json.Unmarshal(raw, &t) == nil
}

Try / catch

if err := merge.Merge(inputs); err != nil {
    if strings.Contains(err.Error(), "invalid tag entry") {
        return fmt.Errorf("fix the tags array in your input specs: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: An input document's root `tags` array contains an element that is not a decodable JSON value (e.g. a raw fragment like a truncated object, or a non-object the struct decode rejects), encountered during mergeTags of that document.

Common situations: Hand-edited spec where a tag was typo'd or truncated; a script appending to `tags` with a malformed element; concatenation bugs producing partially valid JSON.

Related errors


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