{"record":{"id":"1370833341f3f6a6","repo":"wtfutil/wtf","slug":"invalid-property-name-s","errorCode":null,"errorMessage":"invalid property name: %s","messagePattern":"invalid property name: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils/reflective.go","lineNumber":15,"sourceCode":"package utils\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// StringValueForProperty returns a string value for the given property\n// If the property doesn't exist, it returns an error\nfunc StringValueForProperty(ref interface{}, propName string) (string, error) {\n\tv := reflect.ValueOf(ref)\n\trefVal := reflect.Indirect(v).FieldByName(propName)\n\n\tif !refVal.IsValid() {\n\t\treturn \"\", fmt.Errorf(\"invalid property name: %s\", propName)\n\t}\n\n\tstrVal := fmt.Sprintf(\"%v\", refVal)\n\n\treturn strVal, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":22,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/utils/reflective.go#L1-L22","documentation":"StringValueForProperty uses reflection (reflect.Indirect(v).FieldByName(propName)) to read a named struct field as a string. If the struct has no field with that exact name, the returned reflect.Value is invalid and the helper returns 'invalid property name: <propName>'. Matching is exact and case-sensitive, and only exported fields are addressable/named as expected.","triggerScenarios":"A caller passes a struct value and a propName string that doesn't match any field — wrong casing ('Url' vs 'URL'), a field that doesn't exist on that struct type, passing a non-struct (e.g. a map or slice) so FieldByName finds nothing, or the field being embedded/unexported in a way FieldByName can't resolve.","commonSituations":"Config-driven column/attribute names in widget settings that drifted from actual struct field names after a refactor; typos in module config; renaming a Go struct field without updating the config.","solutions":["Compare the configured property name to the struct definition and fix casing/typo (field lookup is exact, e.g. 'URL' not 'Url')","Ensure the value passed is a struct (or pointer to one) containing that field","If a field was renamed, update the config or keep the old name as an alias"],"exampleFix":"// before\nStringValueForProperty(sys, \"Hostname\") // field is Host\n// after\nStringValueForProperty(sys, \"Host\")","handlingStrategy":"type-guard","validationCode":"// validate the property exists before calling\nt := reflect.TypeOf(ref)\nif t.Kind() == reflect.Ptr { t = t.Elem() }\nif t.Kind() != reflect.Struct || _, ok := t.FieldByName(propName); !ok {\n    return fmt.Errorf(\"property %q not found on %s\", propName, t)\n}","typeGuard":"func hasProperty(ref interface{}, propName string) bool {\n    t := reflect.TypeOf(ref)\n    if t == nil { return false }\n    if t.Kind() == reflect.Ptr { t = t.Elem() }\n    if t.Kind() != reflect.Struct { return false }\n    _, ok := t.FieldByName(propName)\n    return ok\n}","tryCatchPattern":"s, err := StringValueForProperty(row, propName)\nif err != nil {\n    log.Printf(\"skipping unknown property %q: %v\", propName, err)\n    return \"\" // don't crash rendering\n}","preventionTips":["Match field names exactly, including casing (URL, ID)","Keep config property names in sync when refactoring struct fields","Prefer typed access over reflection when the schema is known"],"tags":["go","reflection","runtime-error"],"backgroundTag":"invalid-property-name","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}