{"record":{"id":"eaee8b8bdc9f6d7b","repo":"cayleygraph/cayley","slug":"unexpected-type-t","errorCode":null,"errorMessage":"unexpected type: %T","messagePattern":"unexpected type: %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/linkedql/registry.go","lineNumber":269,"sourceCode":"\treturn quad.IRI(s), nil\n}\n\nfunc parseIdentifier(s string) (quad.Value, error) {\n\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","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/query/linkedql/registry.go#L251-L287","documentation":"parseIdentifierString expects its argument to be a map[string]interface{} — a JSON-LD node object like {\"@id\": \"...\"}. When the value is any other type (string, number, bool, array, nil), the type assertion fails and this error is returned. It is the registry's way of rejecting structurally wrong input before looking up the \"@id\" key.","triggerScenarios":"parseValue receiving a raw string or scalar where a node object is required — i.e. passing {\"@id\": \"_:b0\"} fields as plain strings, or passing arrays/nil into value positions that expect node objects.","commonSituations":"Confusion between the two accepted identifier forms: a plain string IRI is valid for parseIdentifier but not for parseIdentifierString; developers pass a string into a slot that requires the node-object form. Also occurs after custom unmarshaling that produces structs instead of map[string]interface{}.","solutions":["Wrap the identifier string in a node object: {\"@id\": \"<value>\"} before passing it where a node object is expected.","Check the enclosing step field's expected shape in the LinkedQL registry docs — some fields take strings, others require {\"@id\": ...}.","If using a custom decoder, decode into map[string]interface{} rather than typed structs for step documents."],"exampleFix":"// before\nparseIdentifierString(\"_:b0\") // string, not map\n// after\nparseIdentifierString(map[string]interface{}{\"@id\": \"_:b0\"})","handlingStrategy":"type-guard","validationCode":"func isNodeObject(v interface{}) bool {\n  _, ok := v.(map[string]interface{})\n  return ok\n}\n// wrap strings: if s, ok := v.(string); ok { v = map[string]interface{}{\"@id\": s} }","typeGuard":"func asNodeObject(v interface{}) (map[string]interface{}, bool) {\n  m, ok := v.(map[string]interface{})\n  return m, ok\n}","tryCatchPattern":"str, err := parseIdentifierString(v)\nif err != nil && strings.HasPrefix(err.Error(), \"unexpected type\") {\n  if s, ok := v.(string); ok {\n    return parseIdentifierString(map[string]interface{}{\"@id\": s})\n  }\n  return fmt.Errorf(\"expected JSON-LD node object, got %T\", v)\n}","preventionTips":["Decode step documents with json.Unmarshal into interface{} so node objects arrive as map[string]interface{}.","Decide on one identifier form (string vs node object) per field and document it.","Add a schema check for step documents before passing them to the registry."],"tags":["go","json-ld","type-error","parsing"],"backgroundTag":"type-mismatch","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"}