weaviate/weaviate · error
date as string expected, got %T
Error message
date as string expected, got %T
What it means
When a class has ObjectTTL configured, keepObjectsWithTTL reads the TTL property value from each result and expects it to be a string (RFC3339 date). If the stored property value is any other Go type, the object cannot be evaluated for expiration and this type-mismatch error is thrown for the whole result set.
Source
Thrown at usecases/traverser/explorer.go:973
}
var expirationTime time.Time
switch class.ObjectTTLConfig.DeleteOn {
case filters.InternalPropCreationTimeUnix:
expirationTime = time.UnixMilli(input.Created)
case filters.InternalPropLastUpdateTimeUnix:
expirationTime = time.UnixMilli(input.Updated)
default:
dateTime, exists := input.Schema.(map[string]interface{})[class.ObjectTTLConfig.DeleteOn]
if !exists {
// if object has no TTL date set, we keep it
return true, nil
}
deleteOnTimeStr, ok := dateTime.(string)
if !ok {
return false, fmt.Errorf("date as string expected, got %T", dateTime)
}
var err error
expirationTime, err = time.Parse(time.RFC3339, deleteOnTimeStr)
if err != nil {
return false, fmt.Errorf("parse date: %w", err)
}
}
expirationThreshold := expirationTime.Add(time.Second * time.Duration(class.ObjectTTLConfig.DefaultTTL))
return expirationThreshold.After(searchStartTime), nil
}
func ExtractDistanceFromParams(params dto.GetParams) (distance float64, withDistance bool) {
if params.NearVector != nil {
distance = params.NearVector.Distance
withDistance = params.NearVector.WithDistance
return distance, withDistance
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Ensure the property named in ObjectTTLConfig contains RFC3339 date strings (e.g. "2026-01-01T00:00:00Z").
- Verify the ttlProperty name is correct — it may be pointing at a numeric or unrelated property.
- Fix or re-import objects whose TTL property holds non-date values.
- Check schema history for a type change on the TTL property and migrate the data if needed.
Example fix
// before — TTL property holds a unix timestamp number
{"deleteOn": 1735689600}
// after — RFC3339 string
{"deleteOn": "2026-01-01T00:00:00Z"} Defensive patterns
Strategy: type-guard
Validate before calling
v, ok := obj.Properties["deleteOn"]
if !ok {
return errors.New("TTL property missing")
}
s, ok := v.(string)
if !ok {
return fmt.Errorf("TTL property must be a string, got %T", v)
}
if _, err := time.Parse(time.RFC3339, s); err != nil {
return fmt.Errorf("TTL property not RFC3339: %w", err)
} Type guard
func isRFC3339String(v interface{}) (string, bool) {
s, ok := v.(string)
if !ok {
return "", false
}
if _, err := time.Parse(time.RFC3339, s); err != nil {
return "", false
}
return s, true
} Try / catch
if err != nil && strings.Contains(err.Error(), "date as string expected") {
// fix data: TTL property holds a non-string value
} Prevention
- Point ObjectTTLConfig.ttlProperty at a property that is genuinely a date string.
- Validate TTL values client-side before every import.
- Never change the TTL property's data type without migrating existing objects.
When it happens
Trigger: The TTL/expiration property contains a non-string value — e.g. the property was created with dataType date and stored as text2vec/time differently, or the configured ttlProperty points at a property whose value is an int/number or a non-date string.
Common situations: Pointing ObjectTTLConfig at the wrong property (one holding a number or unrelated text); importing dates as arbitrary strings; schema type changed from string to date (or vice versa) after objects existed.
Related errors
- parse date: %w
- malformed date aggregator pairs in remote shard result
- malformed date aggregator pair in remote shard result
- unauthorized: namespace claim '%s' is not a string
- unauthorized: global-principal claim '%s' is not a bool
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/3c091af8d60da9e1.
Report an issue: GitHub.