wtfutil/wtf · error

invalid property name: %s

Error message

invalid property name: %s

What it means

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.

Source

Thrown at utils/reflective.go:15

package utils

import (
	"fmt"
	"reflect"
)

// StringValueForProperty returns a string value for the given property
// If the property doesn't exist, it returns an error
func StringValueForProperty(ref interface{}, propName string) (string, error) {
	v := reflect.ValueOf(ref)
	refVal := reflect.Indirect(v).FieldByName(propName)

	if !refVal.IsValid() {
		return "", fmt.Errorf("invalid property name: %s", propName)
	}

	strVal := fmt.Sprintf("%v", refVal)

	return strVal, nil
}

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Compare the configured property name to the struct definition and fix casing/typo (field lookup is exact, e.g. 'URL' not 'Url')
  2. Ensure the value passed is a struct (or pointer to one) containing that field
  3. If a field was renamed, update the config or keep the old name as an alias

Example fix

// before
StringValueForProperty(sys, "Hostname") // field is Host
// after
StringValueForProperty(sys, "Host")
Defensive patterns

Strategy: type-guard

Validate before calling

// validate the property exists before calling
t := reflect.TypeOf(ref)
if t.Kind() == reflect.Ptr { t = t.Elem() }
if t.Kind() != reflect.Struct || _, ok := t.FieldByName(propName); !ok {
    return fmt.Errorf("property %q not found on %s", propName, t)
}

Type guard

func hasProperty(ref interface{}, propName string) bool {
    t := reflect.TypeOf(ref)
    if t == nil { return false }
    if t.Kind() == reflect.Ptr { t = t.Elem() }
    if t.Kind() != reflect.Struct { return false }
    _, ok := t.FieldByName(propName)
    return ok
}

Try / catch

s, err := StringValueForProperty(row, propName)
if err != nil {
    log.Printf("skipping unknown property %q: %v", propName, err)
    return "" // don't crash rendering
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/1370833341f3f6a6. Report an issue: GitHub.