{"record":{"id":"ffeb0b68602c8f65","repo":"grpc-ecosystem/grpc-gateway","slug":"invalid-tag-entry-w","errorCode":null,"errorMessage":"invalid tag entry: %w","messagePattern":"invalid tag entry: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":472,"sourceCode":"\t\treturn raw, nil\n\t}\n\tvar v any\n\tdec := json.NewDecoder(bytes.NewReader(raw))\n\tdec.UseNumber()\n\tif err := dec.Decode(&v); err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(v)\n}\n\n// tagName extracts the `name` field from a tag entry. Tag entries without\n// a name violate the OpenAPI spec and are rejected.\nfunc tagName(raw json.RawMessage) (string, error) {\n\tvar t struct {\n\t\tName string `json:\"name\"`\n\t}\n\tif err := json.Unmarshal(raw, &t); err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid tag entry: %w\", err)\n\t}\n\tif t.Name == \"\" {\n\t\treturn \"\", errors.New(\"tag entry missing required \\\"name\\\"\")\n\t}\n\treturn t.Name, nil\n}\n\n// isJSONNull reports whether raw is the JSON null literal (possibly\n// surrounded by whitespace). Empty input also counts as null.\nfunc isJSONNull(raw json.RawMessage) bool {\n\tif len(raw) == 0 {\n\t\treturn true\n\t}\n\treturn bytes.Equal(bytes.TrimSpace(raw), []byte(\"null\"))\n}\n\n// orderedObject is an insertion-ordered JSON object. It is used for\n// `paths`, `webhooks`, and the bucket of unrecognised top-level keys —","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L454-L490","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Locate the malformed tags entry in the failing input file and fix its JSON syntax","Validate the whole input document with `jq . file.json` before merging","Regenerate the spec from its source generator","Run each input through a JSON Schema/OpenAPI validator to catch structural issues early"],"exampleFix":"// before: {\"tags\":[{\"name\":\"pets\"},{\"name\":\"store\",}]}\n// after:  {\"tags\":[{\"name\":\"pets\"},{\"name\":\"store\"}]}","handlingStrategy":"validation","validationCode":"for _, f := range files {\n    b, err := os.ReadFile(f)\n    if err != nil { return err }\n    var doc struct {\n        Tags []json.RawMessage `json:\"tags\"`\n    }\n    if err := json.Unmarshal(b, &doc); err != nil { return err }\n    for i, t := range doc.Tags {\n        var tag struct{ Name string `json:\"name\"` }\n        if err := json.Unmarshal(t, &tag); err != nil {\n            return fmt.Errorf(\"%s: tags[%d]: %w\", f, i, err)\n        }\n    }\n}","typeGuard":"func isDecodableTagEntry(raw json.RawMessage) bool {\n    var t struct{ Name string `json:\"name\"` }\n    return json.Unmarshal(raw, &t) == nil\n}","tryCatchPattern":"if err := merge.Merge(inputs); err != nil {\n    if strings.Contains(err.Error(), \"invalid tag entry\") {\n        return fmt.Errorf(\"fix the tags array in your input specs: %w\", err)\n    }\n    return err\n}","preventionTips":["Run jq . over every input spec before merging to catch malformed JSON","Validate specs with an OpenAPI linter (e.g. spectral) in CI","Avoid scripts that string-concatenate into tags arrays"],"tags":["go","json","openapi","malformed-input"],"backgroundTag":"json-parse-failed","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}