{"record":{"id":"9952068066be0827","repo":"cayleygraph/cayley","slug":"expected-a-id-key","errorCode":null,"errorMessage":"expected a @id key","messagePattern":"expected a @id key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/linkedql/registry.go","lineNumber":273,"sourceCode":"\tbnode, err := parseBNode(s)\n\tif err == nil {\n\t\treturn bnode, nil\n\t}\n\tiri, err := parseIRI(s)\n\tif err == nil {\n\t\treturn iri, nil\n\t}\n\treturn nil, fmt.Errorf(\"can not parse JSON-LD identifier: %#v\", s)\n}\n\nfunc parseIdentifierString(a interface{}) (string, error) {\n\tm, ok := a.(map[string]interface{})\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"unexpected type: %T\", a)\n\t}\n\tid, ok := m[\"@id\"].(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"expected a @id key\")\n\t}\n\treturn id, nil\n}\n\nfunc parseLiteral(a interface{}) (quad.Value, error) {\n\tswitch a := a.(type) {\n\tcase string:\n\t\treturn quad.String(a), nil\n\tcase int64:\n\t\treturn quad.Int(a), nil\n\tcase float64:\n\t\ti := int64(a)\n\t\tif a == float64(i) {\n\t\t\treturn quad.Int(i), nil\n\t\t}\n\t\treturn quad.Float(a), nil\n\tcase bool:\n\t\treturn quad.Bool(a), nil","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/query/linkedql/registry.go#L255-L291","documentation":"After confirming the input is a map, parseIdentifierString reads m[\"@id\"] and asserts it is a string. If the map has no \"@id\" key — or \"@id\" holds a non-string value like a number or nested object — this error is returned. JSON-LD node objects used as identifiers must carry a string \"@id\" member.","triggerScenarios":"Passing a node object without \"@id\" (e.g. {\"@value\": \"x\"} literal form, or {\"type\": \"Person\"}) or with a non-string \"@id\" (e.g. {\"@id\": 123}) into parseValue/BuildIdentifier paths.","commonSituations":"Using JSON-LD value objects ({\"@value\"/\"@language\"/\"@type\"}) where identifiers are required; documents produced by other JSON-LD tooling that emit @id as a nested structure; typos like \"ID\" or \"id\" instead of \"@id\".","solutions":["Add a string \"@id\" key to the node object: {\"@id\": \"http://example.com/x\"}.","Fix the key spelling/casing — it must be exactly \"@id\".","If the object is a literal, ensure it flows to a literal-accepting field (parseLiteral) rather than an identifier field.","Ensure \"@id\"'s value is a plain JSON string, not a number or nested object."],"exampleFix":"// before\n{\"type\": \"Person\", \"name\": \"Alice\"}\n// after\n{\"@id\": \"http://example.com/people/alice\", \"type\": \"Person\", \"name\": \"Alice\"}","handlingStrategy":"validation","validationCode":"func hasStringID(m map[string]interface{}) bool {\n  id, ok := m[\"@id\"]\n  if !ok { return false }\n  s, ok := id.(string)\n  return ok && s != \"\"\n}\n// if !hasStringID(node) { return errors.New(\"node object requires a string @id\") }","typeGuard":"func extractID(v interface{}) (string, bool) {\n  m, ok := v.(map[string]interface{})\n  if !ok { return \"\", false }\n  s, ok := m[\"@id\"].(string)\n  return s, ok && s != \"\"\n}","tryCatchPattern":"id, err := parseIdentifierString(node)\nif err != nil && err.Error() == \"expected a @id key\" {\n  return fmt.Errorf(\"node %v is a value/literal object, not an identifier: add a string @id\", node)\n}","preventionTips":["Check for the exact key \"@id\" — watch for \"id\"/\"ID\" typos.","Keep literal value objects ({\"@value\": ...}) out of identifier positions.","Validate step documents with a JSON-LD-aware linter before execution."],"tags":["go","json-ld","missing-key","identifier"],"backgroundTag":"schema-validation-failed","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}