cayleygraph/cayley · error

invalid quad at index %d. %s

Error message

invalid quad at index %d. %s

What it means

The HTTP v1 write/delete endpoints parse JSON objects into quad.Quad values. Each parsed quad is validated with q.IsValid(); if subject/predicate/object (or label) combination is invalid — e.g. empty predicate, nil values, or mismatched BNode names — the request is rejected with the index and the invalid quad in the message.

Source

Thrown at internal/http/write.go:55

		Subject   string `json:"subject"`
		Predicate string `json:"predicate"`
		Object    string `json:"object"`
		Label     string `json:"label"`
	}
	err := json.Unmarshal(jsonBody, &quads)
	if err != nil {
		return nil, err
	}
	out = make([]quad.Quad, 0, len(quads))
	for i, jq := range quads {
		q := quad.Quad{
			Subject:   quad.StringToValue(jq.Subject),
			Predicate: quad.StringToValue(jq.Predicate),
			Object:    quad.StringToValue(jq.Object),
			Label:     quad.StringToValue(jq.Label),
		}
		if !q.IsValid() {
			return nil, fmt.Errorf("invalid quad at index %d. %s", i, q)
		}
		out = append(out, q)
	}
	return out, nil
}

const maxQuerySize = 1024 * 1024 // 1 MB
func readLimit(r io.Reader) ([]byte, error) {
	lr := io.LimitReader(r, maxQuerySize).(*io.LimitedReader)
	data, err := ioutil.ReadAll(lr)
	if err != nil && lr.N <= 0 {
		err = errors.New("request is too large")
	}
	return data, err
}

func (api *API) ServeV1Write(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	if api.config.ReadOnly {

View on GitHub (pinned to 81dcd7d73e)

Solutions

  1. Check the quad at the reported index in your JSON array and fix its fields
  2. Ensure subject, predicate, and object are non-empty and provided as strings
  3. Validate quads client-side with quad.StringToValue + IsValid before sending
  4. Log the full request body to find the offending entry

Example fix

// before
{"subject": "", "predicate": "likes", "object": "alice"} // invalid: empty subject
// after
{"subject": "bob", "predicate": "likes", "object": "alice"}
Defensive patterns

Strategy: validation

Validate before calling

for i, jq := range payload.Quads {
    q := quad.Quad{
        Subject: quad.StringToValue(jq.Subject),
        Predicate: quad.StringToValue(jq.Predicate),
        Object: quad.StringToValue(jq.Object),
        Label: quad.StringToValue(jq.Label),
    }
    if !q.IsValid() { return fmt.Errorf("quad %d invalid", i) }
}

Try / catch

resp, err := http.Post(url, "application/json", body)
if err == nil && resp.StatusCode == 400 {
    var e map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&e)
    // inspect error message for the failing index
}

Prevention

When it happens

Trigger: POSTing to /api/v1/write or /delete a JSON body where a quad entry has missing/empty fields, wrong types (numbers instead of strings), or invalid values that quad.StringToValue cannot make valid.

Common situations: Hand-written or generated JSON payloads omitting the "object" field; using null for subject/predicate; BNode labels reused incorrectly; bulk loads with a malformed line mid-array.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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