cayleygraph/cayley · error
blank node ID must start with "_:"
Error message
blank node ID must start with "_:"
What it means
parseBNode converts a JSON-LD string into a quad.BNode, but blank nodes in JSON-LD are only valid when serialized with the "_:" prefix. If the input string lacks that prefix the function refuses to interpret it as a blank node and returns this error. The library enforces the RDF/JSON-LD convention that blank node identifiers are lexically distinguished from IRIs.
Source
Thrown at query/linkedql/registry.go:245
}
func normalizeQuery(data []byte) ([]byte, error) {
var query interface{}
json.Unmarshal(data, &query)
processor := ld.NewJsonLdProcessor()
opts := ld.NewJsonLdOptions("")
compact, err := processor.Compact(query, nil, opts)
if err != nil {
return nil, err
}
return json.Marshal(compact)
}
func parseBNode(s string) (quad.BNode, error) {
if !strings.HasPrefix(s, "_:") {
return "", fmt.Errorf("blank node ID must start with \"_:\"")
}
return quad.BNode(s[2:]), nil
}
func parseIRI(s string) (quad.IRI, error) {
return quad.IRI(s), nil
}
func parseIdentifier(s string) (quad.Value, error) {
bnode, err := parseBNode(s)
if err == nil {
return bnode, nil
}
iri, err := parseIRI(s)
if err == nil {
return iri, nil
}
return nil, fmt.Errorf("can not parse JSON-LD identifier: %#v", s)View on GitHub (pinned to 81dcd7d73e)
Solutions
- Prefix the blank node label with "_:" before passing it, e.g. "_:b0" instead of "b0".
- If the value is actually a resource, use a full absolute IRI (e.g. "http://example.com/b0") so parseIRI handles it instead.
- If the node should be auto-generated, omit the identifier and let the library mint a fresh blank node rather than supplying a bare label.
Example fix
// before
{"@id": "b0"}
// after
{"@id": "_:b0"} Defensive patterns
Strategy: validation
Validate before calling
func isValidBNode(s string) bool { return strings.HasPrefix(s, "_:") && len(s) > 2 }
// before building a step: if !isValidBNode(id) { id = "_:" + id } Prevention
- Normalize all blank node labels with a "_:" prefix helper at document-load time.
- Prefer absolute IRIs unless a blank node is genuinely intended.
- Unit-test step documents against the JSON-LD blank node syntax rules.
When it happens
Trigger: Calling code paths that reach parseBNode (via parseIdentifier during BuildIdentifier or parseValue) with a plain string like "b0" or "node1" instead of "_:b0". This happens when a step's @id value uses a bare label that is not a valid absolute IRI, so parseIRI input falls through or the value is dispatched to blank-node parsing.
Common situations: Hand-written JSON-LD step documents where authors omit the "_:" prefix for blank node references; data produced by tools that output bare internal node labels; copy-pasted node IDs from database exports that strip the prefix.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- can not parse JSON-LD identifier: %#v
- expected a @id key
- unexpected type: %T
- can not parse %#v as a literal
- cannot count iterator without a valid context
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/0f622b681f2d996f.
Report an issue: GitHub.