{"record":{"id":"43a16de326a49979","repo":"ent/ent","slug":"sql-scan-unsupported-type-s","errorCode":null,"errorMessage":"sql/scan: unsupported type ([]%s)","messagePattern":"sql/scan: unsupported type \\(\\[\\](.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dialect/sql/scan.go","lineNumber":159,"sourceCode":"\treturn values\n}\n\n// scanType returns rowScan for the given reflect.Type.\nfunc scanType(typ reflect.Type, columns []string) (*rowScan, error) {\n\tswitch k := typ.Kind(); {\n\tcase assignable(typ):\n\t\treturn &rowScan{\n\t\t\tcolumns: []reflect.Type{typ},\n\t\t\tvalue: func(v ...any) (reflect.Value, error) {\n\t\t\t\treturn reflect.Indirect(reflect.ValueOf(v[0])), nil\n\t\t\t},\n\t\t}, nil\n\tcase k == reflect.Ptr:\n\t\treturn scanPtr(typ, columns)\n\tcase k == reflect.Struct:\n\t\treturn scanStruct(typ, columns)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"sql/scan: unsupported type ([]%s)\", k)\n\t}\n}\n\nvar (\n\ttimeType     = reflect.TypeOf(time.Time{})\n\tscannerType  = reflect.TypeOf((*sql.Scanner)(nil)).Elem()\n\tnullJSONType = reflect.TypeOf((*nullJSON)(nil)).Elem()\n)\n\n// nullJSON represents a json.RawMessage that may be NULL.\ntype nullJSON json.RawMessage\n\n// Scan implements the sql.Scanner interface.\nfunc (j *nullJSON) Scan(v interface{}) error {\n\tif v == nil {\n\t\treturn nil\n\t}\n\t*j = v.([]byte)","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/ent/ent/blob/69d5d4deb19599f129166634e09d33addcf3f2cc/dialect/sql/scan.go#L141-L177","documentation":"scanType only supports element types that are directly scannable (primitives, string, []byte, sql.Scanner implementations), pointers to those, or structs. Any other slice element kind (map, chan, func, slice, interface with methods, invalid) is rejected with this message naming the kind.","triggerScenarios":"Calling ScanSlice with a slice whose element kind is not scannable — e.g. *[]map[string]any, []chan int, [][]int, []func(), or a custom struct-like type that neither implements sql.Scanner nor is a struct.","commonSituations":"Trying to scan raw rows into []map[string]any (a common expectation from other ORMs); passing a slice of slices for multi-column results; typos where the destination should have been a struct.","solutions":["Scan into a slice of structs (or a sql.Scanner-implementing type) whose fields match the selected columns","Implement the sql.Scanner interface on the element type","If dynamic columns are needed, scan into []any / use rows.Scan manually instead of ScanSlice"],"exampleFix":"// before\nvar out []map[string]any\nsql.ScanSlice(rows, &out) // unsupported type ([]map)\n// after\ntype Row struct{ ID int; Name string }\nvar out []Row\nsql.ScanSlice(rows, &out)","handlingStrategy":"type-guard","validationCode":"func scannableElem(t reflect.Type) bool {\n\tswitch t.Kind() {\n\tcase reflect.Struct, reflect.Ptr:\n\t\treturn true\n\tcase reflect.String, reflect.Bool,\n\t\treflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n\t\treflect.Float32, reflect.Float64:\n\t\treturn true\n\t}\n\treturn reflect.PointerTo(t) != nil && t.Implements(scannerType)\n}","typeGuard":"func isScannableSlice(v any) bool {\n\trv := reflect.ValueOf(v)\n\treturn rv.Kind() == reflect.Ptr && rv.Elem().Kind() == reflect.Slice &&\n\t\t(rv.Elem().Type().Elem().Kind() == reflect.Struct ||\n\t\t\trv.Elem().Type().Elem().Implements(reflect.TypeOf((*sql.Scanner)(nil)).Elem()))\n}","tryCatchPattern":null,"preventionTips":["Never pass []map[string]any or slices of slices to ScanSlice; use structs","Implement sql.Scanner on custom element types","Use ent's typed generated structs as scan targets"],"tags":["sql","reflection","unsupported-type"],"backgroundTag":"unsupported-scan-type","analyzedSha":"69d5d4deb19599f129166634e09d33addcf3f2cc","analyzedAt":"2026-09-03T16:51:39.799Z","contentChangedAt":"2026-09-03T16:51:39.799Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}