{"record":{"id":"7872c9431bec837e","repo":"cayleygraph/cayley","slug":"nil-destination-object","errorCode":null,"errorMessage":"nil destination object","messagePattern":"nil destination object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/loader.go","lineNumber":100,"sourceCode":"// All fields in structs are interpreted as required (except slices), thus struct will not be\n// loaded if one of fields is missing. An \"optional\" tag can be specified to relax this requirement.\n// Also, \"required\" can be specified for slices to alter default value.\n//\n//\ttype Person struct{\n//\t\tID quad.IRI `json:\"@id\"`\n//\t\tName string `json:\"name\"` // required field\n//\t\tThirdName string `quad:\"thirdName,optional\"` // can be empty\n//\t\tFollowedBy []quad.IRI `quad:\"follows\"`\n// \t}\nfunc (c *Config) LoadTo(ctx context.Context, qs graph.QuadStore, dst interface{}, ids ...quad.Value) error {\n\treturn c.LoadToDepth(ctx, qs, dst, -1, ids...)\n}\n\n// LoadToDepth is the same as LoadTo, but stops at a specified depth.\n// Negative value means unlimited depth, and zero means top level only.\nfunc (c *Config) LoadToDepth(ctx context.Context, qs graph.QuadStore, dst interface{}, depth int, ids ...quad.Value) error {\n\tif dst == nil {\n\t\treturn fmt.Errorf(\"nil destination object\")\n\t}\n\tvar it iterator.Shape\n\tif len(ids) != 0 {\n\t\tfixed := iterator.NewFixed()\n\t\tfor _, id := range ids {\n\t\t\tidv, err := qs.ValueOf(id)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfixed.Add(idv)\n\t\t}\n\t\tit = fixed\n\t}\n\tvar rv reflect.Value\n\tif v, ok := dst.(reflect.Value); ok {\n\t\trv = v\n\t} else {\n\t\trv = reflect.ValueOf(dst)","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/schema/loader.go#L82-L118","documentation":"Config.LoadToDepth loads graph nodes into a destination object via reflection. A nil dst interface gives reflection nothing to write into, so the loader fails fast with this error before touching the quad store.","triggerScenarios":"Calling LoadTo/LoadToDepth(ctx, qs, dst, ...) with a nil interface{} or an untyped nil variable as dst.","commonSituations":"Declaring var dst *MyType (nil pointer) instead of dst := &MyType{}; passing a nil result from another call straight into LoadTo.","solutions":["Pass a pointer to an allocated struct: dst := &MyType{}; then c.LoadTo(ctx, qs, dst, id...).","Guard the call site with if dst != nil before invoking LoadTo/LoadToDepth.","If dst is a pointer variable, initialize it with new(MyType) or a composite literal."],"exampleFix":"// before\nvar dst *Person\nc.LoadTo(ctx, qs, dst, quad.IRI(\"/person/alice\"))\n// after\ndst := &Person{}\nc.LoadTo(ctx, qs, dst, quad.IRI(\"/person/alice\"))","handlingStrategy":"type-guard","validationCode":"if dst == nil {\n    return errors.New(\"destination must be a non-nil struct pointer\")\n}\nif rv := reflect.ValueOf(dst); rv.Kind() != reflect.Ptr || rv.IsNil() {\n    return errors.New(\"destination must be a pointer to struct\")\n}","typeGuard":"func isNonNilStructPtr(dst interface{}) bool {\n    rv := reflect.ValueOf(dst)\n    return rv.Kind() == reflect.Ptr && !rv.IsNil() && rv.Elem().Kind() == reflect.Struct\n}","tryCatchPattern":"if err := c.LoadTo(ctx, qs, dst, ids...); err != nil {\n    if err.Error() == \"nil destination object\" {\n        return fmt.Errorf(\"caller bug: uninitialized destination: %w\", err)\n    }\n    return err\n}","preventionTips":["Always allocate destinations with &T{} or new(T).","Never pass nil interface{} as an out-parameter.","Add a helper wrapper that validates dst before LoadTo."],"tags":["go","reflection","nil-pointer"],"backgroundTag":"null-argument","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}