{"record":{"id":"f6969c3a0933f3a0","repo":"cayleygraph/cayley","slug":"cannot-scan-t-to-nodehash","errorCode":null,"errorMessage":"cannot scan %T to NodeHash","messagePattern":"cannot scan %T to NodeHash","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/sql/quadstore.go","lineNumber":85,"sourceCode":"\ntype NodeHash struct {\n\trefs.ValueHash\n}\n\nfunc (h NodeHash) SQLValue() interface{} {\n\tif !h.Valid() {\n\t\treturn nil\n\t}\n\treturn []byte(h.ValueHash[:])\n}\nfunc (h *NodeHash) Scan(src interface{}) error {\n\tif src == nil {\n\t\t*h = NodeHash{}\n\t\treturn nil\n\t}\n\tb, ok := src.([]byte)\n\tif !ok {\n\t\treturn fmt.Errorf(\"cannot scan %T to NodeHash\", src)\n\t}\n\tif len(b) == 0 {\n\t\t*h = NodeHash{}\n\t\treturn nil\n\t} else if len(b) != quad.HashSize {\n\t\treturn fmt.Errorf(\"unexpected hash length: %d\", len(b))\n\t}\n\tcopy(h.ValueHash[:], b)\n\treturn nil\n}\n\nfunc HashOf(s quad.Value) NodeHash {\n\treturn NodeHash{refs.HashOf(s)}\n}\n\ntype QuadHashes struct {\n\trefs.QuadHash\n}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/sql/quadstore.go#L67-L103","documentation":"NodeHash.Scan implements sql.Scanner; it requires the driver to deliver the hash as a []byte. If the database/driver returns any other Go type (string, int64, etc.), Scan returns \"cannot scan %T to NodeHash\". This is a type mismatch between driver output and the expected binary hash column.","triggerScenarios":"Calling rows.Scan (via QuadStore.Scan / iterator scanning) into NodeHash when the column is not stored as binary/BLOB, so the driver returns e.g. string or []uint8-adjacent non-byte types.","commonSituations":"Schema where hash columns are TEXT/VARCHAR instead of BLOB/BINARY; drivers that decode hex hashes into strings (different MySQL driver, Postgres text mode); using a driver whose value conversion differs.","solutions":["Store/alias hash columns as binary types (BLOB/BINARY/BYTEA) so the driver returns []byte.","Check driver settings that force text/return protocol and switch to binary parameters.","Scan into a string or sql.RawBytes first and convert to NodeHash via HashOf/decoding yourself.","Ensure the schema was created by the store's own Init so column types match."],"exampleFix":"// before\nvar h NodeHash\nrows.Scan(&h) // driver returns string\n// after\nvar s string\nrows.Scan(&s)\nh := HashOf(quad.Raw(s))","handlingStrategy":"validation","validationCode":"// ensure hash columns are binary so the driver returns []byte\n// check schema: information_schema.columns WHERE data_type IN ('blob','binary','bytea')","typeGuard":null,"tryCatchPattern":"var h NodeHash\nif err := rows.Scan(&h); err != nil {\n    if strings.HasPrefix(err.Error(), \"cannot scan\") {\n        // scan into string/raw bytes and convert manually\n    }\n}","preventionTips":["Create schemas with the store's own Init so hash columns are binary.","Configure drivers for binary result mode.","Don't change hash column types to TEXT/VARCHAR."],"tags":["sql","scan","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}