cayleygraph/cayley · error

unexpected type for float field: %T

Error message

unexpected type for float field: %T

What it means

toQuadValue converts the float value field to quad.Float; this error is thrown when the stored fldValFloat field is neither nosql.Int nor nosql.Float. The value document's float slot holds an unexpected Go/nosql type, so the quad value cannot be reconstructed.

Source

Thrown at graph/nosql/quadstore.go:568

			if vs, ok := d[fldValStrInt].(nosql.String); ok {
				iv := quad.Int(stoi(string(vs)))
				return iv, nil
			}
		}
		vi, err := asInt(v)
		if err != nil {
			return nil, err
		}
		return quad.Int(vi), nil
	} else if v, ok := d[fldValFloat]; ok {
		var vf quad.Float
		switch v := v.(type) {
		case nosql.Int:
			vf = quad.Float(v)
		case nosql.Float:
			vf = quad.Float(v)
		default:
			return nil, fmt.Errorf("unexpected type for float field: %T", v)
		}
		return vf, nil
	} else if v, ok := d[fldValBool]; ok {
		var vb quad.Bool
		switch v := v.(type) {
		case nosql.Bool:
			vb = quad.Bool(v)
		default:
			return nil, fmt.Errorf("unexpected type for bool field: %T", v)
		}
		return vb, nil
	} else if v, ok := d[fldValTime]; ok {
		var vt quad.Time
		switch v := v.(type) {
		case nosql.Time:
			vt = quad.Time(v)
		case nosql.String:
			var t time.Time

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Log %T of the value to identify the stored type and the writer that produced it.
  2. Re-import the affected data with the current Cayley version so floats are stored as nosql.Float.
  3. Fix custom writers to encode numbers as nosql.Float (or nosql.Int).
  4. Dump/re-load the quadstore to normalize value encodings if migration drift is suspected.

Example fix

// before
default:
    return nil, fmt.Errorf("unexpected type for float field: %T", v)
// after
case nosql.String:
    f, err := strconv.ParseFloat(string(v), 64)
    if err != nil {
        return nil, fmt.Errorf("float field not parseable: %w", err)
    }
    vf = quad.Float(f)
default:
    return nil, fmt.Errorf("unexpected type for float field: %T", v)
Defensive patterns

Strategy: type-guard

Validate before calling

func isFloatLike(v nosql.Value) bool {
    switch v.(type) {
    case nosql.Int, nosql.Float:
        return true
    }
    return false
}

Type guard

func asFloatSafe(v interface{}) (quad.Float, bool) {
    switch t := v.(type) {
    case nosql.Int:
        return quad.Float(t), true
    case nosql.Float:
        return quad.Float(t), true
    }
    return 0, false
}

Try / catch

val, err := toQuadValue(opt, doc)
if err != nil {
    log.Printf("bad float field %T, skipping value: %v", doc[fldValFloat], err)
    return quad.Raw(""), nil
}

Prevention

When it happens

Trigger: Reading a quad value written as a float by an incompatible encoder that stored nosql.String/Bytes/Bool in the float field, or a corrupted/hand-edited document.

Common situations: Cross-version data migration (value encoding changes); custom import tools writing plain JSON numbers that the driver stores as string; corruption from a failed write.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06). Data as JSON: /api/errors/5e2841dc4333b75c. Report an issue: GitHub.