{"record":{"id":"7bdc1271ff1c3a48","repo":"siyuan-note/siyuan","slug":"bazaar-response-variant-is-not-set","errorCode":null,"errorMessage":"bazaar response variant is not set","messagePattern":"bazaar response variant is not set","errorType":"exception","errorClass":null,"httpStatus":500,"severity":"error","filePath":"kernel/apicontract/bazaar.go","lineNumber":387,"sourceCode":"type BazaarRatingResult struct {\n\tsuccess *BazaarRatingData\n\tfailure *BazaarRatingError\n}\n\nfunc NewBazaarRatingResult(data BazaarRatingData) BazaarRatingResult {\n\treturn BazaarRatingResult{success: &data}\n}\nfunc NewBazaarRatingResultError(data BazaarRatingError) BazaarRatingResult {\n\treturn BazaarRatingResult{failure: &data}\n}\nfunc (data BazaarRatingResult) MarshalJSON() ([]byte, error) {\n\tif data.success != nil {\n\t\treturn json.Marshal(data.success)\n\t}\n\tif data.failure != nil {\n\t\treturn json.Marshal(data.failure)\n\t}\n\treturn nil, errors.New(\"bazaar response variant is not set\")\n}\n\ntype BazaarUserRatingsResult struct {\n\tsuccess *BazaarUserRatingsData\n\tfailure *BazaarRatingError\n}\n\nfunc NewBazaarUserRatingsResult(data BazaarUserRatingsData) BazaarUserRatingsResult {\n\treturn BazaarUserRatingsResult{success: &data}\n}\nfunc NewBazaarUserRatingsResultError(data BazaarRatingError) BazaarUserRatingsResult {\n\treturn BazaarUserRatingsResult{failure: &data}\n}\nfunc (data BazaarUserRatingsResult) MarshalJSON() ([]byte, error) {\n\tif data.success != nil {\n\t\treturn json.Marshal(data.success)\n\t}\n\tif data.failure != nil {","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/bazaar.go#L369-L405","documentation":"BazaarUserRatingsResult is a success/failure union (BazaarUserRatingsData or BazaarRatingError); MarshalJSON serializes the set variant and returns this error when both pointers are nil. The union type exists so the marketplace ratings endpoint can only produce a well-formed success or error body.","triggerScenarios":"Marshaling a BazaarUserRatingsResult created as a zero value or via a struct literal without NewBazaarUserRatingsResult/NewBazaarUserRatingsResultError, typically in the getBazaarPackageUserRatings response path.","commonSituations":"Handler builds the result only inside a branch and returns the default otherwise; refactoring removed a constructor call; upstream rating fetch fails and neither variant is assigned.","solutions":["Use NewBazaarUserRatingsResult / NewBazaarUserRatingsResultError on all paths","Return the BazaarRatingError failure variant when the upstream ratings call fails","Test that every branch of the handler marshals successfully"],"exampleFix":"// before\nvar result apicontract.BazaarUserRatingsResult\nreturn result\n// after\nreturn apicontract.NewBazaarUserRatingsResultError(apicontract.BazaarRatingError{Msg: msg})","handlingStrategy":"validation","validationCode":"func checkBazaarUserRatings(r apicontract.BazaarUserRatingsResult) error {\n    if _, err := json.Marshal(r); err != nil {\n        return fmt.Errorf(\"ratings result unset: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"payload, err := json.Marshal(result)\nif err != nil {\n    return Response[apicontract.BazaarUserRatingsResult]{Code: 1, Msg: err.Error()}\n}","preventionTips":["Always use NewBazaarUserRatingsResult / NewBazaarUserRatingsResultError","Assign the failure variant when the upstream ratings fetch errors","Test both success and failure branches of the endpoint"],"tags":["go","json-marshal","union-type","bazaar"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}