cayleygraph/cayley · error
unsupported time format: %T: %v
Error message
unsupported time format: %T: %v
What it means
The SQL quadstore scans time column values into a NullTime wrapper supporting a limited set of driver value shapes (e.g. []byte/string in "2006-01-02 15:04:05.999999", time.Time, etc.). If the driver returns a value whose Go type isn't handled by the switch, Scan reports this error including the Go type (%T) and value.
Source
Thrown at graph/sql/quadstore.go:604
}
// Scan implements the Scanner interface.
func (nt *NullTime) Scan(value interface{}) error {
if value == nil {
nt.Time, nt.Valid = time.Time{}, false
return nil
}
switch value := value.(type) {
case time.Time:
nt.Time, nt.Valid = value, true
case []byte:
t, err := time.Parse("2006-01-02 15:04:05.999999", string(value))
if err != nil {
return err
}
nt.Time, nt.Valid = t, true
default:
return fmt.Errorf("unsupported time format: %T: %v", value, value)
}
return nil
}
// Value implements the driver Valuer interface.
func (nt NullTime) Value() (driver.Value, error) {
if !nt.Valid {
return nil, nil
}
return nt.Time, nil
}
func (qs *QuadStore) NameOf(v graph.Ref) (quad.Value, error) {
if v == nil {
return nil, nil
} else if v, ok := v.(refs.PreFetchedValue); ok {
return v.NameOf(), nil
}View on GitHub (pinned to 81dcd7d73e)
Solutions
- Check the actual timestamp format stored in the database column and align it with "2006-01-02 15:04:05.999999"
- Set the connection DSN to return time as time.Time (e.g. parseTime=true for MySQL) so Scan receives driver.Time instead of a string
- Normalize the column values (UPDATE table SET col = STR_TO_DATE(...)) to the expected format
- Extend NullTypedTime.Scan to handle the driver's representation in your fork
Example fix
// before
db, _ := sql.Open("mysql", "user:pw@/db") // returns strings for DATETIME
// after
db, _ := sql.Open("mysql", "user:pw@/db?parseTime=true") // returns time.Time Defensive patterns
Strategy: try-catch
Validate before calling
if !strings.Contains(err.Error(), "unsupported time format") {
return err
}
// else fix DSN/format and retry once Type guard
if bt, ok := value.([]byte); ok {
_, err := time.Parse("2006-01-02 15:04:05.999999", string(bt))
return err
}
return fmt.Errorf("unexpected time value type %T", value) Try / catch
val, err := qs.NameOf(h)
if err != nil && strings.Contains(err.Error(), "unsupported time format") {
// reconfigure driver to return time.Time (e.g. parseTime=true) and retry
} Prevention
- Set driver DSNs to return time.Time rather than strings
- Keep DB timestamp columns in a format matching "2006-01-02 15:04:05.999999"
- Pin and test the driver version used with the quadstore
When it happens
Trigger: A database driver returning timestamps in an unexpected representation, e.g. a string with timezone info like "2020-01-02T03:04:05Z" that fails Parse, or []uint8 with a nonstandard date format for that DB.
Common situations: MySQL driver returning DATE/DATETIME in a format with fractional-second or timezone differences; switching drivers so NullTypedTime.Scan receives raw strings it can't parse; storing timestamps written by other tools in a different format.
Related errors
- sql query failed: %v query: %v
- cannot scan %T to NodeHash
- unsupported sql database: %q
- unexpected token: %T
- error executing value lookup: %w
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/4f0ef2162e6ca237.
Report an issue: GitHub.