cayleygraph/cayley · error

Unknown JSON type: %T

Error message

Unknown JSON type: %T

What it means

buildShape in mql/build_iterator.go:93 switches over the Go type of each value in the MQL query JSON. Recognized types are []interface{}, map[string]interface{}, and nil; any other JSON scalar type (string, float64, bool) hits the default branch and produces this error. MQL query values must be objects, arrays, or null — not raw scalars.

Source

Thrown at query/mql/build_iterator.go:93

	case []interface{}:
		// for JSON arrays
		q.isRepeated[path] = true
		if len(t) == 0 {
			s = buildAllResult(path)
			optional = true
		} else if len(t) == 1 {
			s, optional, err = q.buildShape(t[0], path)
		} else {
			err = fmt.Errorf("multiple fields at location root %s", path.DisplayString())
		}
	case map[string]interface{}:
		// for JSON objects
		s, err = q.buildShapeMap(t, path)
	case nil:
		s = buildAllResult(path)
		optional = true
	default:
		err = fmt.Errorf("Unknown JSON type: %T", query)
	}
	if err != nil {
		return nil, false, err
	}
	s = shape.Save{
		From: s,
		Tags: []string{string(path)},
	}
	return s, optional, nil
}

func (q *Query) buildShapeMap(query map[string]interface{}, path Path) (shape.Shape, error) {
	it := shape.IntersectOpt{
		Sub: shape.Intersect{
			shape.AllNodes{},
		},
	}
	outputStructure := make(map[string]interface{})

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Replace scalar values with nil (match anything) or a nested query array/map.
  2. Restructure the query so scalar constraints are expressed as sub-fields or separate filtering.
  3. Check the %T in the message to identify the unexpected scalar type.
  4. Sanitize/validate query JSON before calling BuildIteratorTree.

Example fix

// before
query := map[string]interface{}{"name": "bob"}
// after
query := map[string]interface{}{"name": nil} // or nested spec
Defensive patterns

Strategy: validation

Validate before calling

func validateMQLValueTypes(q map[string]interface{}) error {
  for k, v := range q {
    switch v.(type) {
    case nil, []interface{}, map[string]interface{}:
    default:
      return fmt.Errorf("field %q: MQL values must be null, array, or object, got %T", k, v)
    }
  }
  return nil
}

Type guard

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

Try / catch

it, err := mql.BuildIteratorTree(query)
if err != nil {
  if strings.Contains(err.Error(), "Unknown JSON type") {
    return fmt.Errorf("replace scalar field values with nil or nested specs")
  }
  return err
}

Prevention

When it happens

Trigger: Running a MQL query containing a scalar value where a field spec is expected, e.g. {"name": "bob"} instead of {"name": nil} or {"name": [...]}.

Common situations: Authors coming from MongoDB-style MQL expecting scalar equality matching; the Cayley MQL dialect only accepts null (wildcard) or arrays/maps as values.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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