kataras/iris · error

ISO8601: unknown type of: %T

Error message

ISO8601: unknown type of: %T

What it means

ISO8601 implements sql.Scanner; Scan dispatches on the runtime type of the database driver's src value. Supported types are string, []byte, time.Time, and nil. This error is returned when the driver hands Scan a value of any other type, so the library cannot convert it into an ISO8601 time.

Source

Thrown at x/jsonx/iso8601.go:397

func (t *ISO8601) Scan(src any) error {
	switch v := src.(type) {
	case time.Time: // type was set to timestamp
		if v.IsZero() {
			return nil // don't set zero, ignore it.
		}
		*t = ISO8601(v)
	case string:
		tt, err := ParseISO8601(v)
		if err != nil {
			return err
		}
		*t = tt
	case []byte:
		return t.Scan(string(v))
	case nil:
		*t = ISO8601(time.Time{})
	default:
		return fmt.Errorf("ISO8601: unknown type of: %T", v)
	}

	return nil
}

// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
// The function checks for a signed number in the range -23 through +23 excluding zero.
// Returns length of the found offset string or 0 otherwise.
//
// Language internal function.
func parseSignedOffset(value string) int {
	sign := value[0]
	if sign != '-' && sign != '+' {
		return 0
	}
	x, rem, err := leadingInt(value[1:])

	// fail if nothing consumed by leadingInt

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Change the SQL column/query to return a timestamp, text, or bytea type the scanner supports (e.g. SELECT to_timestamp(epoch) instead of raw epoch).
  2. Convert the value in SQL (e.g. epoch::text) or in code before calling Scan.
  3. Use a custom wrapper type that converts int64 epoch values to time.Time and delegates to ISO8601.

Example fix

// before
var t jsonx.ISO8601
rows.Scan(&t) // BIGINT column -> ISO8601: unknown type of: int64
// after
var epoch int64
rows.Scan(&epoch)
t = jsonx.ISO8601(time.Unix(epoch, 0).UTC())
Defensive patterns

Strategy: type-guard

Validate before calling

func scanSrcSupported(src any) bool {
	switch src.(type) {
	case nil, string, []byte, time.Time:
		return true
	default:
		return false
	}
}

Type guard

func isScannableIntoISO8601(src any) bool {
	switch src.(type) {
	case nil, string, []byte, time.Time:
		return true
	}
	return false
}

Try / catch

var t jsonx.ISO8601
if err := rows.Scan(&t); err != nil {
	if strings.Contains(err.Error(), "unknown type of") {
		return fmt.Errorf("column is not a timestamp/text type; convert it in SQL: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling (*ISO8601).Scan(src) with src whose concrete type is not time.Time, string, []byte, or nil — e.g. an int64 from a BIGINT column, float64, or a driver-specific type.

Common situations: Binding an ISO8601 field to a non-temporal SQL column (integer epoch, numeric); custom drivers returning exotic types; scanning raw query results with mismatched column types.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/e83e857d6256608e. Report an issue: GitHub.