{"record":{"id":"a59ae638f677c83a","repo":"ory/hydra","slug":"cannot-scan-v-into-stringslicejsonformat","errorCode":null,"errorMessage":"cannot scan %#v into StringSliceJSONFormat","messagePattern":"cannot scan %#v into StringSliceJSONFormat","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/sqlxx/types.go","lineNumber":61,"sourceCode":"}\n\n// StringSliceJSONFormat represents []string{} which is encoded to/from JSON for SQL storage.\n// swagger:type array\ntype StringSliceJSONFormat []string\n\n// Scan implements the Scanner interface.\nfunc (m *StringSliceJSONFormat) Scan(value interface{}) error {\n\tvar val string\n\tswitch v := value.(type) {\n\tcase nil:\n\t\t*m = StringSliceJSONFormat{}\n\t\treturn nil\n\tcase string:\n\t\tval = v\n\tcase []byte:\n\t\tval = string(v)\n\tdefault:\n\t\treturn errors.Errorf(\"cannot scan %#v into StringSliceJSONFormat\", value)\n\t}\n\tif len(val) == 0 {\n\t\tval = \"[]\"\n\t}\n\n\tif parsed := gjson.Parse(val); parsed.Type == gjson.Null {\n\t\tval = \"[]\"\n\t} else if !parsed.IsArray() {\n\t\treturn errors.Errorf(\"expected JSON value to be an array but got type: %s\", parsed.Type.String())\n\t}\n\n\treturn errors.WithStack(json.Unmarshal([]byte(val), &m))\n}\n\n// Value implements the driver Valuer interface.\nfunc (m StringSliceJSONFormat) Value() (driver.Value, error) {\n\tif len(m) == 0 {\n\t\treturn \"[]\", nil","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/sqlxx/types.go#L43-L79","documentation":"StringSliceJSONFormat implements sql.Scanner for a []string stored as JSON. Its Scan accepts nil, string, and []byte only; any other driver value (int, float64, time.Time, bool, etc.) is rejected with this error. It indicates the source column is not a text/JSON column carrying a JSON array document.","triggerScenarios":"Scanning a column of numeric, boolean, timestamp, or native-JSON-object-driver type into a *StringSliceJSONFormat field; raw queries returning non-text expressions into that field; a driver that decodes JSONB into non-string types.","commonSituations":"Model field changed from a string slice to a scalar but the Scan type was left in place; column switched from TEXT/JSONB to BIGINT; migrating data where an old column held CSV/integer ids now being read into the JSON-based type.","solutions":["Change the column to TEXT or JSON/JSONB storing a JSON array (e.g. '[\"a\",\"b\"]') via a migration.","Cast in SQL: SELECT col::text FROM ... so the driver delivers a string/[]byte.","Scan into the driver's native Go type first, marshal it to a JSON array, then assign to StringSliceJSONFormat.","If the column truly holds scalars, change the model field type — StringSliceJSONFormat is only for arrays."],"exampleFix":"// before\nrows.Scan(&tags) // tags is sqlxx.StringSliceJSONFormat; column is INT -> error\n\n// after\nrows.Scan(\"SELECT tags::text\")\n// or migrate column: ALTER TABLE items ALTER COLUMN tags TYPE jsonb USING ...;","handlingStrategy":"type-guard","validationCode":"var dataType string\nerr := db.QueryRow(`SELECT data_type FROM information_schema.columns\n  WHERE table_name=$1 AND column_name=$2`, \"items\", \"tags\").Scan(&dataType)\n// acceptable: \"text\", \"character varying\", \"json\", \"jsonb\"","typeGuard":"func scannableIntoStringSlice(v any) bool {\n    switch v.(type) {\n    case nil, string, []byte:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"var tags sqlxx.StringSliceJSONFormat\nif err := rows.Scan(&tags); err != nil {\n    if strings.Contains(err.Error(), \"cannot scan\") {\n        // column returned a non-text driver type; fetch as text or fix column\n        return fmt.Errorf(\"tags column is not text/json: %w\", err)\n    }\n    return err\n}","preventionTips":["Store string slices in TEXT or JSONB columns containing JSON arrays.","Cast to ::text in raw queries feeding StringSliceJSONFormat fields.","Keep model field types in sync with column types when refactoring schemas.","Test Scan behavior against each supported driver in CI."],"tags":["database","scan","json","type-mismatch"],"backgroundTag":"sql-scan-type-mismatch","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}