jmoiron/sqlx · error

Incompatible type for GzippedText

Error message

Incompatible type for GzippedText

What it means

GzippedText.Scan implements sql.Scanner and accepts only string or []byte source values (the raw gzipped bytes from the DB). Any other driver-returned type cannot be interpreted as gzip input, so Scan returns this error. The error text is capitalized because changing it would break consumers (see lint ignore).

Source

Thrown at types/types.go:39

	w := gzip.NewWriter(buf)
	w.Write(g)
	w.Close()
	return buf.Bytes(), nil

}

// Scan implements the sql.Scanner interface, ungzipping the value coming off
// the wire and storing the raw result in the GzippedText.
func (g *GzippedText) Scan(src interface{}) error {
	var source []byte
	switch src := src.(type) {
	case string:
		source = []byte(src)
	case []byte:
		source = src
	default:
		//lint:ignore ST1005 changing this could break consumers of this package
		return errors.New("Incompatible type for GzippedText")
	}
	reader, err := gzip.NewReader(bytes.NewReader(source))
	if err != nil {
		return err
	}
	defer reader.Close()
	b, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	*g = GzippedText(b)
	return nil
}

// JSONText is a json.RawMessage, which is a []byte underneath.
// Value() validates the json format in the source, and returns an error if
// the json is not valid.  Scan does no validation.  JSONText additionally
// implements `Unmarshal`, which unmarshals the json within to an interface{}

View on GitHub (pinned to 41dac167fd)

Solutions

  1. Ensure the DB column stores gzipped data as a binary/text type the driver returns as []byte or string.
  2. If the driver returns another type, scan into a []byte first and set GzippedText via its Set method.
  3. Check driver behavior/version for how BLOB/TEXT values are returned.
  4. If the data is not actually gzip, use plain Text/JSONText instead.

Example fix

// before
var g types.GzippedText
row.Scan(&g) // driver returns float64
// after
var raw []byte
row.Scan(&raw)
g.Set(raw)
Defensive patterns

Strategy: type-guard

Validate before calling

func gzippable(src interface{}) bool {
	switch src.(type) {
	case []byte, string, nil:
		return true
	default:
		return false
	}
}

Type guard

func isByteLike(v interface{}) bool {
	switch v.(type) {
	case []byte, string:
		return true
	}
	return false
}

Try / catch

var g types.GzippedText
if err := row.Scan(&g); err != nil {
	if err.Error() == "Incompatible type for GzippedText" {
		// inspect database/sql's returned type via reflect.TypeOf
	}
	return err
}

Prevention

When it happens

Trigger: Scanning a GzippedText column where the driver returns a non-string/non-[]byte value, e.g. an int64/float64 (numeric column) or time.Time, into a GzippedText field.

Common situations: Column declared as an integer/BLOB-adjacent type or the driver encodes blobs differently (e.g. some drivers return string, others []byte); using a driver that returns custom types; pointing GzippedText at a non-gzip column.

Related errors


AI-assisted analysis of jmoiron/sqlx@41dac167fd (2026-09-03). Data as JSON: /api/errors/330d74099a46e1af. Report an issue: GitHub.