cayleygraph/cayley · error

wrong quad format: ' ': no predicate

Error message

wrong quad format: '%s': no predicate

What it means

The schema parser failed to extract a predicate from a quad-shaped rule string. Rules of the form 'predicate[ value]' must contain a non-empty predicate before the space; an empty predicate part makes the rule meaningless, so generation aborts. This comes from strings.SplitN of the rule string where the first segment trimmed to empty.

Solutions

  1. Fix the struct tag so it begins with a valid predicate IRI or string, e.g. `tag:"name"`
  2. Remove stray leading spaces/colons from the rule string before the predicate
  3. Print the offending rule (the %s in the message) and compare against documented quad format 'predicate [value]'

Example fix

// before
type Person struct {
    Name string `tag:" nickname"`
}
// after
type Person struct {
    Name string `tag:"nickname"`
}
Defensive patterns

Strategy: validation

Validate before calling

for _, s := range rules {
    s = strings.TrimSpace(strings.SplitN(s, " ", 2)[0])
    if s == "" {
        return fmt.Errorf("rule %q has empty predicate", s)
    }
}

Prevention

When it happens

Trigger: Calling Generate on a struct whose tagged rule string starts with a space, contains only whitespace before the value separator (e.g. `tag:",someIRI"`), or is effectively empty after trimming.

Common situations: Typos in struct tags like `tag:":value"` or `tag:" value"`; programmatically built rule strings with accidental leading separators; copy-pasted RDF lines missing the predicate column.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at schema/schema.go:194

			return nil, fmt.Errorf("wrong quad tag format: '%s'", rule)
		}
	} else { // s-p>o // default
		tri = strings.SplitN(rule, spo, 3)
		if len(tri) > 2 { //len(tri) != 2 {
			return nil, fmt.Errorf("wrong quad tag format: '%s'", rule)
		}
	}
	var ps, vs string
	if rev {
		ps, vs = strings.Trim(tri[0], trim), strings.Trim(tri[1], trim)
	} else {
		ps, vs = strings.Trim(tri[0], trim), any
		if len(tri) > 1 {
			vs = strings.Trim(tri[1], trim)
		}
	}
	if ps == "" {
		return nil, fmt.Errorf("wrong quad format: '%s': no predicate", rule)
	}
	p := c.toIRI(ps)
	if vs == "" || vs == any && fld.Type != reflEmptyStruct {
		return saveRule{Pred: p, Rev: rev, Opt: opt}, nil
	}
	return constraintRule{Pred: p, Val: c.toIRI(vs), Rev: rev}, nil
}

func checkFieldType(ftp reflect.Type) error {
	for ftp.Kind() == reflect.Ptr || ftp.Kind() == reflect.Slice {
		ftp = ftp.Elem()
	}
	switch ftp.Kind() {
	case reflect.Array: // TODO: support arrays
		return fmt.Errorf("array fields are not supported yet")
	case reflect.Func, reflect.Invalid:
		return fmt.Errorf("%v fields are not supported", ftp.Kind())
	default:

View on GitHub (pinned to 81dcd7d73e)