{"record":{"id":"680aa3763d6feaf9","repo":"gocolly/colly","slug":"invalid-type-or-nil-pointer","errorCode":null,"errorMessage":"Invalid type or nil-pointer","messagePattern":"Invalid type or nil-pointer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"unmarshal.go","lineNumber":55,"sourceCode":"// Allowed struct tags:\n//   - \"selector\" (required): CSS (goquery) selector of the desired data\n//   - \"attr\" (optional): Selects the matching element's attribute's value.\n//     Leave it blank or omit to get the text of the element.\n//\n// Example struct declaration:\n//\n//\ttype Nested struct {\n//\t\tString  string   `selector:\"div > p\"`\n//\t   Classes []string `selector:\"li\" attr:\"class\"`\n//\t\tStruct  *Nested  `selector:\"div > div\"`\n//\t}\n//\n// Supported types: struct, *struct, string, []string\nfunc UnmarshalHTML(v interface{}, s *goquery.Selection, structMap map[string]string) error {\n\trv := reflect.ValueOf(v)\n\n\tif rv.Kind() != reflect.Ptr || rv.IsNil() {\n\t\treturn errors.New(\"Invalid type or nil-pointer\")\n\t}\n\n\tsv := rv.Elem()\n\tst := reflect.TypeOf(v).Elem()\n\tif structMap != nil {\n\t\tfor k, v := range structMap {\n\t\t\tattrV := sv.FieldByName(k)\n\t\t\tif !attrV.CanAddr() || !attrV.CanSet() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err := unmarshalSelector(s, attrV, v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < sv.NumField(); i++ {\n\t\t\tattrV := sv.Field(i)\n\t\t\tif !attrV.CanAddr() || !attrV.CanSet() {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/gocolly/colly/blob/17d1d6ca92bd32a5651f34256bf7a2855c967f65/unmarshal.go#L37-L73","documentation":"UnmarshalHTML requires its first argument to be a non-nil pointer to the struct being populated. If v is not a pointer or is a nil pointer, it returns \"Invalid type or nil-pointer\" (unmarshal.go:55) via reflection checks on reflect.ValueOf(v).","triggerScenarios":"Calling colly.UnmarshalHTML with a struct value instead of &struct, or with a nil pointer variable; also propagated when nested UnmarshalHTML calls receive non-pointer elements.","commonSituations":"Passing MyStruct{} instead of &MyStruct{}; a typed nil (*MyStruct)(nil); map/slice elements that are values not pointers; misusing the API after switching from Unmarshal to UnmarshalHTML.","solutions":["Pass a pointer to your struct: UnmarshalHTML(&result, sel, nil)","Initialize the pointer before the call (result := &MyStruct{})","Check the argument's type at the call site; only *struct is accepted","Handle the returned error to catch programming mistakes early"],"exampleFix":"// before\nvar s MyStruct\ncolly.UnmarshalHTML(s, sel, nil)\n// after\ns := &MyStruct{}\nerr := colly.UnmarshalHTML(s, sel, nil)","handlingStrategy":"validation","validationCode":"if v == nil || reflect.ValueOf(v).Kind() != reflect.Ptr || reflect.ValueOf(v).IsNil() {\n    return fmt.Errorf(\"UnmarshalHTML needs a non-nil struct pointer\")\n}","typeGuard":"func isUnmarshalTarget(v interface{}) bool {\n    rv := reflect.ValueOf(v)\n    return rv.Kind() == reflect.Ptr && !rv.IsNil() && rv.Elem().Kind() == reflect.Struct\n}","tryCatchPattern":"if err := colly.UnmarshalHTML(&result, sel, nil); err != nil {\n    if err.Error() == \"Invalid type or nil-pointer\" {\n        log.Println(\"check argument: must be non-nil *struct\")\n    }\n    return err\n}","preventionTips":["Always pass &T{} not T{} to unmarshal functions","Initialize pointer targets before calling","Add a unit test exercising each Unmarshal call site","Keep struct targets non-generic so reflection kinds are predictable"],"tags":["reflection","unmarshal","go"],"backgroundTag":"invalid-argument-type","analyzedSha":"17d1d6ca92bd32a5651f34256bf7a2855c967f65","analyzedAt":"2026-08-30T21:32:31.579Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}