{"record":{"id":"1883d15c48d92830","repo":"geektutu/7days-golang","slug":"invalid-sql-type-s-s-1883d1","errorCode":null,"errorMessage":"invalid sql type %s (%s)","messagePattern":"invalid sql type (.+?) \\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-orm/day3-save-query/dialect/sqlite3.go","lineNumber":38,"sourceCode":"\tcase reflect.Bool:\n\t\treturn \"bool\"\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:\n\t\treturn \"integer\"\n\tcase reflect.Int64, reflect.Uint64:\n\t\treturn \"bigint\"\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn \"real\"\n\tcase reflect.String:\n\t\treturn \"text\"\n\tcase reflect.Array, reflect.Slice:\n\t\treturn \"blob\"\n\tcase reflect.Struct:\n\t\tif _, ok := typ.Interface().(time.Time); ok {\n\t\t\treturn \"datetime\"\n\t\t}\n\t}\n\tpanic(fmt.Sprintf(\"invalid sql type %s (%s)\", typ.Type().Name(), typ.Kind()))\n}\n\n// TableExistSQL returns SQL that judge whether the table exists in database\nfunc (s *sqlite3) TableExistSQL(tableName string) (string, []interface{}) {\n\targs := []interface{}{tableName}\n\treturn \"SELECT name FROM sqlite_master WHERE type='table' and name = ?\", args\n}\n","sourceCodeStart":20,"sourceCodeEnd":46,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-orm/day3-save-query/dialect/sqlite3.go#L20-L46","documentation":"Identical to error 103 but in the day3-save-query stage: the sqlite3 dialect panics with 'invalid sql type' when Schema.Parse encounters a field type it cannot map to a SQLite column type. Only basic kinds and time.Time are supported; all other kinds fail fast.","triggerScenarios":"Calling geeorm.Open(db, &Model{...}) where Model has a field of unsupported kind (map, slice, embedded struct, custom kind) causing schema parse to call DataTypeOf with an unmappable type.","commonSituations":"Adding a new struct field for a feature and immediately opening a session against it; using pointer fields; storing collections directly in the row.","solutions":["Use a supported Go type for the field or serialize to string/[]byte","Register a custom dialect mapping if you control the dialect code","Remove the field from the persisted struct or move it to a related table"],"exampleFix":"// before\ntype Order struct {\n    Items []string\n}\n// after\ntype Order struct {\n    Items string // JSON-encoded []string\n}","handlingStrategy":"validation","validationCode":"func checkSchemaTypes(v interface{}) error {\n    t := reflect.TypeOf(v).Elem()\n    for i := 0; i < t.NumField(); i++ {\n        k := t.Field(i).Type.Kind()\n        if k == reflect.Struct && t.Field(i).Type != reflect.TypeOf(time.Time{}) {\n            return fmt.Errorf(\"field %s: unsupported %s\", t.Field(i).Name, t.Field(i).Type)\n        }\n        if k == reflect.Map || k == reflect.Interface || k == reflect.Ptr {\n            return fmt.Errorf(\"field %s: unsupported kind %s\", t.Field(i).Name, k)\n        }\n    }\n    return nil\n}","typeGuard":"func isSQLiteMappable(t reflect.Type) bool {\n    if t == reflect.TypeOf(time.Time{}) { return true }\n    switch t.Kind() {\n    case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n        reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n        reflect.Float32, reflect.Float64, reflect.String, reflect.Slice:\n        return true\n    }\n    return false\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && strings.HasPrefix(s, \"invalid sql type\") {\n            err = fmt.Errorf(\"unsupported model field: %s\", s)\n        } else { panic(r) }\n    }\n}()","preventionTips":["Avoid map/slice-of-struct/interface fields in ORM models","Encode complex values as JSON strings before persisting","Add a schema sanity unit test per model"],"tags":["go","panic","sqlite","orm","schema"],"backgroundTag":"unsupported-field-type","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}