{"record":{"id":"7377bac3ad72a5e5","repo":"micro/go-micro","slug":"invalid-error-v","errorCode":null,"errorMessage":"invalid error %v","messagePattern":"invalid error (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"codec/jsonrpc/client.go","lineNumber":80,"sourceCode":"}\n\nfunc (c *clientCodec) ReadHeader(m *codec.Message) error {\n\tc.resp.reset()\n\tif err := c.dec.Decode(&c.resp); err != nil {\n\t\treturn err\n\t}\n\n\tc.Lock()\n\tm.Method = c.pending[c.resp.ID]\n\tdelete(c.pending, c.resp.ID)\n\tc.Unlock()\n\n\tm.Error = \"\"\n\tm.Id = fmt.Sprintf(\"%v\", c.resp.ID)\n\tif c.resp.Error != nil {\n\t\tx, ok := c.resp.Error.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid error %v\", c.resp.Error)\n\t\t}\n\t\tif x == \"\" {\n\t\t\tx = \"unspecified error\"\n\t\t}\n\t\tm.Error = x\n\t}\n\treturn nil\n}\n\nfunc (c *clientCodec) ReadBody(x interface{}) error {\n\tif x == nil || c.resp.Result == nil {\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(*c.resp.Result, x)\n}\n\nfunc (c *clientCodec) Close() error {\n\treturn c.c.Close()","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/codec/jsonrpc/client.go#L62-L98","documentation":"The JSON-RPC client's ReadHeader parses the response envelope; the JSON-RPC spec allows the 'error' member to be any JSON value, but this codec only supports string errors. When resp.Error is present but not a JSON string (e.g. an object like {code, message, data} per the JSON-RPC 2.0 spec), ReadHeader returns 'invalid error' and the call fails instead of surfacing the server's error text.","triggerScenarios":"Calling a JSON-RPC server that returns a structured error object (JSON-RPC 2.0 style {code:-32600,...}) while this client expects resp.Error to be a plain string.","commonSituations":"Interoperating with standard JSON-RPC 2.0 servers (Go net/rpc jsonrpc or third-party) that encode errors as objects; proxying requests to services using the official spec; version mismatch between client expectations and server implementation.","solutions":["Make the server return its error as a plain string in the 'error' field.","Patch/extend the client to handle object errors (extract 'message' from the object) instead of erroring.","Use a different transport (e.g. grpc or the micro json codec) that matches the server's error format.","Log the raw response to confirm the error shape before changing code."],"exampleFix":"// before (server)\nreturn nil, &jsonrpcError{Code: -32600, Message: \"bad request\"}\n// after\nreturn nil, errors.New(\"bad request\")","handlingStrategy":"type-guard","validationCode":"// Server side: only send string errors so this client can parse them.\n// Client side: inspect the raw envelope before decoding if possible.\nfunc errIsString(raw json.RawMessage) bool {\n\treturn len(raw) > 0 && raw[0] == '\"'\n}","typeGuard":"func errAsString(v interface{}) (string, bool) {\n\ts, ok := v.(string)\n\treturn s, ok\n}","tryCatchPattern":"if err := client.Call(ctx, req, resp); err != nil {\n\tif strings.HasPrefix(err.Error(), \"invalid error\") {\n\t\t// server sent a non-string JSON-RPC error object; inspect raw response\n\t}\n\treturn err\n}","preventionTips":["Ensure your JSON-RPC server returns plain-string 'error' values.","Avoid pairing this client with strict JSON-RPC 2.0 servers that use error objects.","Pin server/client versions so error formats stay aligned.","Capture raw responses in a debug mode to diagnose error-shape mismatches."],"tags":["jsonrpc","codec","error-parsing","interoperability"],"backgroundTag":"jsonrpc-invalid-error-payload","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}