cayleygraph/cayley · error

unexpected value type for %v: %T

Error message

unexpected value type for %v: %T

What it means

When translating limit/skip constraints, iterateObject requires the single value to be a quad.Int; any other value type (string, float, bool) returns this error naming the key and the offending Go type. This enforces that pagination parameters are integers.

Source

Thrown at query/graphql/graphql.go:177

	} else {
		p = p.LabelContext()
	}
	var (
		limit = -1
		skip  = 0
	)

	for _, h := range f.Has {
		switch h.Via {
		case quad.IRI(ValueKey): // special key - "id"
			p = p.Is(h.Values...)
		case quad.IRI(LimitKey), quad.IRI(SkipKey): // limit and skip
			if len(h.Values) != 1 {
				return nil, fmt.Errorf("unexpected arguments: %v (%d)", h.Values, len(h.Values))
			}
			n, ok := h.Values[0].(quad.Int)
			if !ok {
				return nil, fmt.Errorf("unexpected value type for %v: %T", string(h.Via), h.Values[0])
			}
			if h.Via == quad.IRI(LimitKey) {
				limit = int(n)
			} else {
				skip = int(n)
				if skip < 0 {
					skip = 0
				}
			}
		default: // everything else - Has constraint
			if len(h.Labels) != 0 {
				p = p.LabelContext(h.Labels)
			}
			if h.Rev {
				p = p.HasReverse(h.Via, h.Values...)
			} else {
				p = p.Has(h.Via, h.Values...)
			}

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Convert the value to quad.Int before building the Has constraint (quad.Int(n)).
  2. Ensure the GraphQL layer coerces integer-typed fields and rejects strings at parse time.
  3. If you receive this from user input, validate that limit/skip are integers (no quotes) in the request.

Example fix

// before
Values: []interface{}{quad.String("10")}
// after
Values: []interface{}{quad.Int(10)}
Defensive patterns

Strategy: validation

Validate before calling

if (typeof limit !== 'number' || !Number.isInteger(limit)) throw new Error('limit/skip must be integers');

Type guard

func isQuadInt(v interface{}) bool { _, ok := v.(quad.Int); return ok }

Try / catch

out, err := iterateObject(ctx, qs, field, p)
if err != nil && strings.Contains(err.Error(), "unexpected value type") { /* coerce to quad.Int */ }

Prevention

When it happens

Trigger: A limit/skip value that is not a quad.Int — e.g. quad.String("10"), a float, or a boolean — passed in the Has constraint at query/graphql/graphql.go:177.

Common situations: Queries with quoted numbers (limit: "10"), JSON parsers producing float64 for integers that were never converted to quad.Int, or hand-built constraint lists in Go code.

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