cayleygraph/cayley · error
cannot scan %T to NodeHash
Error message
cannot scan %T to NodeHash
What it means
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.
Source
Thrown at graph/sql/quadstore.go:85
type NodeHash struct {
refs.ValueHash
}
func (h NodeHash) SQLValue() interface{} {
if !h.Valid() {
return nil
}
return []byte(h.ValueHash[:])
}
func (h *NodeHash) Scan(src interface{}) error {
if src == nil {
*h = NodeHash{}
return nil
}
b, ok := src.([]byte)
if !ok {
return fmt.Errorf("cannot scan %T to NodeHash", src)
}
if len(b) == 0 {
*h = NodeHash{}
return nil
} else if len(b) != quad.HashSize {
return fmt.Errorf("unexpected hash length: %d", len(b))
}
copy(h.ValueHash[:], b)
return nil
}
func HashOf(s quad.Value) NodeHash {
return NodeHash{refs.HashOf(s)}
}
type QuadHashes struct {
refs.QuadHash
}View on GitHub (pinned to 81dcd7d73e)
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.
Example fix
// before var h NodeHash rows.Scan(&h) // driver returns string // after var s string rows.Scan(&s) h := HashOf(quad.Raw(s))
Defensive patterns
Strategy: validation
Validate before calling
// ensure hash columns are binary so the driver returns []byte
// check schema: information_schema.columns WHERE data_type IN ('blob','binary','bytea') Try / catch
var h NodeHash
if err := rows.Scan(&h); err != nil {
if strings.HasPrefix(err.Error(), "cannot scan") {
// scan into string/raw bytes and convert manually
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- unexpected hash length: %d
- unsupported time format: %T: %v
- unexpected token: %T
- not a SQL quadstore: %T
- token not valid
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/f6969c3a0933f3a0.
Report an issue: GitHub.