cayleygraph/cayley · error

unexpected type for int field: %T

Error message

unexpected type for int field: %T

What it means

asInt converts a NoSQL document field to an integer and throws this error when the stored value is neither nosql.Int nor nosql.Float. It indicates the value document contains a field of an unexpected Go type, typically meaning the stored data was written by an incompatible writer or the wrong field was read.

Source

Thrown at graph/nosql/quadstore.go:518

	case quad.Bool:
		doc = nosql.Document{fldValBool: nosql.Bool(d)}
	case quad.Time:
		doc = nosql.Document{fldValTime: nosql.Time(time.Time(d).UTC())}
	default:
		encPb()
	}
	return nosql.Document{fldValue: doc}
}

func asInt(v nosql.Value) (nosql.Int, error) {
	var vi nosql.Int
	switch v := v.(type) {
	case nosql.Int:
		vi = v
	case nosql.Float:
		vi = nosql.Int(v)
	default:
		return 0, fmt.Errorf("unexpected type for int field: %T", v)
	}
	return vi, nil
}

func toQuadValue(opt *Traits, d nosql.Document) (quad.Value, error) {
	if len(d) == 0 {
		return nil, nil
	}
	var err error
	// prefer protobuf representation
	if v, ok := d[fldValPb]; ok {
		var b []byte
		switch v := v.(type) {
		case nosql.String:
			b, err = base64.StdEncoding.DecodeString(string(v))
		case nosql.Bytes:
			b = []byte(v)
		default:

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Log %T of the offending value to see what was actually stored and where it was written from.
  2. Re-export and re-load the quadstore data (cayley dump / load) so all values are re-encoded by the current version.
  3. Check for version mismatch: data written by an older Cayley may need the documented migration steps.
  4. Ensure the document actually belongs to the expected field (correct fldVal* key, not a mis-keyed read).
  5. If writing custom tooling against the store, always encode numbers as nosql.Int or nosql.Float.

Example fix

// before
default:
    return 0, fmt.Errorf("unexpected type for int field: %T", v)
// after
case nosql.String:
    n, err := strconv.ParseInt(string(v), 10, 64)
    if err != nil {
        return 0, fmt.Errorf("int field not parseable: %w", err)
    }
    vi = nosql.Int(n)
default:
    return 0, fmt.Errorf("unexpected type for int field: %T", v)
Defensive patterns

Strategy: type-guard

Validate before calling

// validate stored numeric fields before conversion
func isIntLike(v nosql.Value) bool {
    switch v.(type) {
    case nosql.Int, nosql.Float:
        return true
    }
    return false
}

Type guard

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

Try / catch

n, err := asInt(doc[fldSize])
if err != nil {
    log.Printf("bad numeric field %T: %v", doc[fldSize], err)
    // re-import or repair the document instead of proceeding
}

Prevention

When it happens

Trigger: checkQuadValid or toQuadValue reading a numeric field (fldValInt / size counters) that was stored as nosql.String, nosql.Bool, nosql.Time or nosql.Bytes instead of Int/Float — e.g. data written by a different Cayley version or backend encoding.

Common situations: Migrating a quadstore between backends or Cayley versions where value encodings changed (pre/post Number32 support); a corrupt or hand-edited document; reading a field name that collides with another value kind.

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/6ea0821719dbb0a7. Report an issue: GitHub.