cayleygraph/cayley · error
multiple fields at location root %s
Error message
multiple fields at location root %s
What it means
In mql/build_iterator.go:84, buildShape handles a JSON array in the MQL query. An array at the root represents alternative field shapes; more than one element means multiple fields were specified at the same root location, which MQL does not support, so this error is thrown with the path's display string. A single-element array or empty array (match-all) are the only allowed forms.
Source
Thrown at query/mql/build_iterator.go:84
if math.Floor(t) == t {
// Treat it like an integer.
s = shape.Lookup{quad.Int(t)}
} else {
s = shape.Lookup{quad.Float(t)}
}
case string:
// for JSON strings
s = buildFixed(t)
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, nilView on GitHub (pinned to 81dcd7d73e)
Solutions
- Reduce the array at that location to a single field object.
- Merge the multiple field definitions into one map if they should apply together.
- Use separate queries if the alternatives are mutually exclusive.
- Check the path string in the message to locate the offending query position.
Example fix
// before
query := []interface{}{map[string]interface{}{"name": nil}, map[string]interface{}{"age": nil}}
// after
query := map[string]interface{}{"name": nil, "age": nil} Defensive patterns
Strategy: validation
Validate before calling
func validateMQLArrayAtMostOne(v interface{}) error {
arr, ok := v.([]interface{})
if !ok || len(arr) <= 1 { return nil }
return fmt.Errorf("MQL arrays may contain at most one field spec, got %d", len(arr))
} Type guard
func isSingleSpecArray(v interface{}) bool {
a, ok := v.([]interface{})
return ok && len(a) <= 1
} Try / catch
it, err := mql.BuildIteratorTree(query)
if err != nil {
if strings.Contains(err.Error(), "multiple fields at location root") {
return fmt.Errorf("merge multiple field objects into one in query")
}
return err
} Prevention
- Merge field sets into a single map instead of multi-element arrays
- Keep query generators emitting one spec per location
- Validate MQL query JSON against the dialect before execution
When it happens
Trigger: Executing a MQL query (mql.BuildIteratorTree) where a JSON array value contains two or more field definitions at the same location, e.g. [[{...},{...}]] style multiple alternatives.
Common situations: Hand-writing MQL queries that mix multiple top-level field sets, or programmatic query generation emitting an array with multiple query maps.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- optional iterator at the top level
- Unknown JSON type: %T
- required field is missing
- Datastore: invalid action
- cannot count iterator without a valid context
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/641dd205af609b7c.
Report an issue: GitHub.