{"record":{"id":"1b7f59e43715cc27","repo":"cayleygraph/cayley","slug":"expected-struct-got-v","errorCode":null,"errorMessage":"expected struct, got %v","messagePattern":"expected struct, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/loader.go","lineNumber":176,"sourceCode":"\nfunc (c *Config) newLoader(qs graph.QuadStore) *loader {\n\treturn &loader{\n\t\tc:  c,\n\t\tqs: qs,\n\n\t\tpathForType:     make(map[reflect.Type]*path.Path),\n\t\tpathForTypeRoot: make(map[reflect.Type]*path.Path),\n\n\t\tseen: make(map[quad.Value]reflect.Value),\n\t}\n}\n\nfunc (l *loader) makePathForType(rt reflect.Type, tagPref string, rootOnly bool) (*path.Path, error) {\n\tfor rt.Kind() == reflect.Ptr {\n\t\trt = rt.Elem()\n\t}\n\tif rt.Kind() != reflect.Struct {\n\t\treturn nil, fmt.Errorf(\"expected struct, got %v\", rt)\n\t}\n\tif tagPref == \"\" {\n\t\tm := l.pathForType\n\t\tif rootOnly {\n\t\t\tm = l.pathForTypeRoot\n\t\t}\n\t\tif p, ok := m[rt]; ok {\n\t\t\treturn p, nil\n\t\t}\n\t}\n\n\tp := path.StartMorphism()\n\n\tif iri := getTypeIRI(rt); iri != quad.IRI(\"\") {\n\t\tp = p.Has(l.c.iri(iriType), iri)\n\t}\n\n\t// TODO(dennwc): rewrite to shapes","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/schema/loader.go#L158-L194","documentation":"makePathForType builds a schema path for a Go type, dereferencing pointers first. If after unwrapping the type's Kind is not Struct, the schema mapping machinery cannot proceed, so it returns this error naming the offending type.","triggerScenarios":"Registering or loading a schema for a non-struct type: e.g. iteratorForType/makePathForType called with a slice, map, string, or interface type (or a pointer to one), or a struct field whose type is not a struct when recursion descends into it via makePathForType.","commonSituations":"Passing &[]Person{} (slice) as the destination; a schema tag pointing at a field of type map[string]string; registering Config.AddType with a non-struct value.","solutions":["Ensure the destination/registered type is a struct (or pointer to struct); change var dst []Person usage to load into a struct wrapper or use a slice-aware loader path.","If the field should be a collection, annotate it appropriately rather than letting the loader recurse into it as a schema root.","Wrap scalar data in a struct: type Result struct { Value string `quad:\"@id\"` }."],"exampleFix":"// before\npeople := []Person{}\nc.LoadTo(ctx, qs, &people)\n// after\nresult := struct{ People []Person `quad:\"person\"` }{}\nc.LoadTo(ctx, qs, &result)","handlingStrategy":"type-guard","validationCode":"rt := reflect.TypeOf(dst)\nfor rt != nil && rt.Kind() == reflect.Ptr { rt = rt.Elem() }\nif rt == nil || rt.Kind() != reflect.Struct {\n    return errors.New(\"schema destination/registration type must be a struct\")\n}","typeGuard":"func isStructType(v interface{}) bool {\n    t := reflect.TypeOf(v)\n    for t != nil && t.Kind() == reflect.Ptr { t = t.Elem() }\n    return t != nil && t.Kind() == reflect.Struct\n}","tryCatchPattern":"if err := c.LoadTo(ctx, qs, dst, ids...); err != nil {\n    if strings.Contains(err.Error(), \"expected struct, got\") {\n        return fmt.Errorf(\"schema type mismatch: %w\", err)\n    }\n    return err\n}","preventionTips":["Only register/load structs (or pointers to structs) with schema.Config.","Check embedded and tagged field types are structs where the schema recurses.","Compile-time assertion: var _ = isStructType(Person{}) in tests."],"tags":["go","reflection","schema","type-mismatch"],"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"}