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

  1. Ensure the property named in ObjectTTLConfig contains RFC3339 date strings (e.g. "2026-01-01T00:00:00Z").
  2. Verify the ttlProperty name is correct — it may be pointing at a numeric or unrelated property.
  3. Fix or re-import objects whose TTL property holds non-date values.
  4. 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

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


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/3c091af8d60da9e1. Report an issue: GitHub.