{"record":{"id":"2ef2414e961828eb","repo":"geektutu/7days-golang","slug":"invalid-sql-type-s-s-2ef241","errorCode":null,"errorMessage":"invalid sql type %s (%s)","messagePattern":"invalid sql type (.+?) \\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-orm/day7-migrate/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/day7-migrate/dialect/sqlite3.go#L20-L46","documentation":"Same 'invalid sql type' panic in the day7-migrate stage of gee-orm. During migration the schema is parsed and each field's type is mapped via the sqlite3 dialect; a field kind outside the supported switch (bool/int/float/string/[]byte/time.Time) panics with this message.","triggerScenarios":"Running geeorm migration (Open/MigrateModel) on a struct that contains a slice, map, nested struct, or other unmappable field type.","commonSituations":"Migrating a table whose model grew complex fields; version changes where a string field became a custom type; developers modeling documents in relational columns.","solutions":["Normalize the field to a supported type or serialize it into a string/[]byte column","Add the needed kind mapping to the sqlite3 dialect","Split complex fields into separate tables"],"exampleFix":"// before\ntype Product struct {\n    Attributes map[string]string\n}\n// after\ntype Product struct {\n    Attributes string // JSON encoded map\n}","handlingStrategy":"validation","validationCode":"for _, f := range reflect.VisibleFields(reflect.TypeOf(Product{})) {\n    if !isSQLiteMappable(f.Type) {\n        log.Fatalf(\"migration blocked: field %s (%s) unsupported\", f.Name, f.Type)\n    }\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(\"migration failed on unsupported field: %s\", s)\n        } else { panic(r) }\n    }\n}()","preventionTips":["Audit models for map/slice/struct fields before running migrations","Store serialized JSON in string columns for complex data","Run migration against a test DB in CI to catch schema issues early"],"tags":["go","panic","sqlite","orm","schema","migration"],"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"}