{"record":{"id":"12a0400a702b232f","repo":"kataras/iris","slug":"unsupported-response-body-type-t","errorCode":null,"errorMessage":"unsupported response body type: %T","messagePattern":"unsupported response body type: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/client/client.go","lineNumber":456,"sourceCode":"\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch ptr := dest.(type) {\n\tcase *[]byte:\n\t\t*ptr = body\n\t\treturn nil\n\tcase *string:\n\t\t*ptr = string(body)\n\t\treturn nil\n\tcase *int:\n\t\t*ptr, err = strconv.Atoi(string(body))\n\t\treturn err\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported response body type: %T\", ptr)\n\t}\n}\n\n// GetPlainUnquote reads the response body as raw text and tries to unquote it,\n// useful when the remote server sends a single key as a value but due to backend mistake\n// it sends it as JSON (quoted) instead of plain text.\nfunc (c *Client) GetPlainUnquote(ctx context.Context, method, urlpath string, payload any, opts ...RequestOption) (string, error) {\n\tvar bodyStr string\n\tif err := c.ReadPlain(ctx, &bodyStr, method, urlpath, payload, opts...); err != nil {\n\t\treturn \"\", err\n\t}\n\n\ts, err := strconv.Unquote(bodyStr)\n\tif err == nil {\n\t\tbodyStr = s\n\t}\n\n\treturn bodyStr, nil","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/x/client/client.go#L438-L474","documentation":"Client.ReadPlain reads a response body as plain text and only knows how to bind it into *[]byte, *string, or *int. If dest is any other type it returns this error naming the concrete Go type it received. It is a programming/usage error: the wrong destination pointer was passed to ReadPlain.","triggerScenarios":"Calling client.ReadPlain(ctx, dest, method, urlpath, ...) where dest is not *[]byte, *string or *int — e.g. passing a *map[string]any, *struct pointer, or *float64. Also triggered indirectly if GetPlainUnquote's internal *string path is altered; GetPlainUnquote itself is safe since it always passes a *string.","commonSituations":"Refactoring code from ReadJSON to ReadPlain and forgetting to change the destination to a plain-type pointer; copy-pasting a ReadJSON call with a struct pointer into ReadPlain; passing a typed alias like *MyString (whose underlying type differs at the type-switch level) instead of *string.","solutions":["Pass a pointer to string, []byte, or int as dest (e.g. var s string; client.ReadPlain(ctx, &s, ...)).","If you need structured data, use ReadJSON instead of ReadPlain.","For custom types, read into a *string/*[]byte and convert/unmarshal manually afterwards.","Read the %T in the error message to identify the wrongly-typed variable at the call site."],"exampleFix":"// before\nvar result map[string]any\nerr := client.ReadPlain(ctx, &result, http.MethodGet, \"/api/value\", nil)\n\n// after\nvar s string\nerr := client.ReadPlain(ctx, &s, http.MethodGet, \"/api/value\", nil)\n// or use ReadJSON for structured types","handlingStrategy":"type-guard","validationCode":"func readPlainDestOK(dest any) bool {\n    switch dest.(type) {\n    case *string, *[]byte, *int:\n        return true\n    default:\n        return false\n    }\n}\n// if !readPlainDestOK(&dest) { use ReadJSON or convert dest }","typeGuard":"func isReadPlainDest(dest any) bool {\n    switch dest.(type) {\n    case *string, *[]byte, *int:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err := client.ReadPlain(ctx, dest, method, path, nil); err != nil {\n    if strings.HasPrefix(err.Error(), \"unsupported response body type:\") {\n        // programmer error: wrong dest type; do not retry, fix call site\n        return fmt.Errorf(\"ReadPlain misuse: %w\", err)\n    }\n    return err\n}","preventionTips":["Only pass &string, &[]byte or &int to ReadPlain; route structured types to ReadJSON.","Watch out for named/alias types (*MyString is not *string in a type switch).","Wrap ReadPlain in a small helper with a constrained generic signature: func readPlain[T ~string | ~[]byte | ~int].","Add a unit test per call site exercising the dest type."],"tags":["go","http-client","type-mismatch","developer-error"],"backgroundTag":"unsupported-destination-type","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}