{"record":{"id":"989c19de16df6304","repo":"canopy-network/canopy","slug":"unknown-parameter-type-t","errorCode":null,"errorMessage":"unknown parameter type %T","messagePattern":"unknown parameter type %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fsm/message_helpers.go","lineNumber":355,"sourceCode":"\t\treturn ErrInvalidProposalHash()\n\t}\n\treturn nil\n}\n\n// MarshalJSON() is the json.Marshaller implementation for MessageChangeParameter\nfunc (x MessageChangeParameter) MarshalJSON() ([]byte, error) {\n\ta, err := lib.FromAny(x.ParameterValue)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar parameterValue any\n\tswitch p := a.(type) {\n\tcase *lib.StringWrapper:\n\t\tparameterValue = p.Value\n\tcase *lib.UInt64Wrapper:\n\t\tparameterValue = p.Value\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown parameter type %T\", p)\n\t}\n\treturn json.Marshal(jsonMessageChangeParameter{\n\t\tParameterSpace: x.ParameterSpace,\n\t\tParameterKey:   x.ParameterKey,\n\t\tParameterValue: parameterValue,\n\t\tStartHeight:    x.StartHeight,\n\t\tEndHeight:      x.EndHeight,\n\t\tSigner:         x.Signer,\n\t\tProposalHash:   x.ProposalHash,\n\t})\n}\n\n// UnmarshalJSON() is the json.Unmarshaler implementation for MessageChangeParameter\nfunc (x *MessageChangeParameter) UnmarshalJSON(b []byte) (err error) {\n\tvar j jsonMessageChangeParameter\n\tif err = json.Unmarshal(b, &j); err != nil {\n\t\treturn\n\t}","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/fsm/message_helpers.go#L337-L373","documentation":"MessageChangeParameter.MarshalJSON serializes the parameter value only when it is a *lib.StringWrapper or *lib.UInt64Wrapper (stored in a protobuf Any). Any other wrapped type hits the default branch and returns 'unknown parameter type %T'.","triggerScenarios":"json.Marshal is called on a MessageChangeParameter whose Any payload contains a wrapper type other than StringWrapper/UInt64Wrapper (e.g. BoolWrapper, BytesWrapper, or a custom message).","commonSituations":"A governance parameter was stored with a new wrapper kind added to the proto but the JSON marshaling switch was not updated, or an older/newer node version produces a wrapper type this code doesn't know.","solutions":["Add a case for the actual wrapper type in the type switch in MarshalJSON (fsm/message_helpers.go:~347)","Convert the parameter to StringWrapper or UInt64Wrapper before storing/submitting the ChangeParameter message","Check proto definitions to confirm which wrapper type is used and align client-side serialization"],"exampleFix":"// before\ncase *lib.UInt64Wrapper:\n    parameterValue = p.Value\ndefault:\n    return nil, fmt.Errorf(\"unknown parameter type %T\", p)\n// after\ncase *lib.UInt64Wrapper:\n    parameterValue = p.Value\ncase *lib.BoolWrapper:\n    parameterValue = p.Value\ndefault:\n    return nil, fmt.Errorf(\"unknown parameter type %T\", p)","handlingStrategy":"type-guard","validationCode":"switch v := param.Value.(type) {\ncase *lib.StringWrapper, *lib.UInt64Wrapper:\n    // ok, marshalable\ndefault:\n    return fmt.Errorf(\"unsupported param wrapper %T\", v)\n}","typeGuard":"func marshalableParam(a *anypb.Any) bool {\n    var s lib.StringWrapper; var u lib.UInt64Wrapper\n    return a != nil && (a.UnmarshalTo(&s) == nil || a.UnmarshalTo(&u) == nil)\n}","tryCatchPattern":"b, err := json.Marshal(msg)\nif err != nil && strings.Contains(err.Error(), \"unknown parameter type\") {\n    // reject/normalize the parameter wrapper before retrying\n}","preventionTips":["Only store StringWrapper or UInt64Wrapper as ChangeParameter values","Add a case to the type switch whenever a new wrapper type is introduced","Keep client and node versions in sync on parameter wrapper types"],"tags":["json","marshaling","protobuf-any","type-switch"],"backgroundTag":"json-marshal-failed","analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}