{"record":{"id":"b96e2de9995ed20b","repo":"wailsapp/wails","slug":"missing-type-field-in","errorCode":null,"errorMessage":"missing Type field in ","messagePattern":"missing Type field in ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v2/internal/typescriptify/typescriptify.go","lineNumber":358,"sourceCode":"func (t *TypeScriptify) AddEnum(values interface{}) *TypeScriptify {\n\tif t.enums == nil {\n\t\tt.enums = map[reflect.Type][]enumElement{}\n\t}\n\titems := reflect.ValueOf(values)\n\tif items.Kind() != reflect.Slice {\n\t\tpanic(fmt.Sprintf(\"Values for %T isn't a slice\", values))\n\t}\n\n\tvar elements []enumElement\n\tfor i := 0; i < items.Len(); i++ {\n\t\titem := items.Index(i)\n\n\t\tvar el enumElement\n\t\tif item.Kind() == reflect.Struct {\n\t\t\tr := reflector.New(item.Interface())\n\t\t\tval, err := r.Field(\"Value\").Get()\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Sprint(\"missing Type field in \", item.Type().String()))\n\t\t\t}\n\t\t\tname, err := r.Field(\"TSName\").Get()\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Sprint(\"missing TSName field in \", item.Type().String()))\n\t\t\t}\n\t\t\tel.value = val\n\t\t\tel.name = name.(string)\n\t\t} else {\n\t\t\tel.value = item.Interface()\n\t\t\tif tsNamer, is := item.Interface().(TSNamer); is {\n\t\t\t\tel.name = tsNamer.TSName()\n\t\t\t} else {\n\t\t\t\tpanic(fmt.Sprint(item.Type().String(), \" has no TSName method\"))\n\t\t\t}\n\t\t}\n\n\t\telements = append(elements, el)\n\t}","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v2/internal/typescriptify/typescriptify.go#L340-L376","documentation":"Inside AddEnum, each slice element that is a struct is reflected upon and must expose a field named 'Value'; if the reflector cannot read r.Field(\"Value\"), the generator panics with 'missing Type field in <Type>'. (The message text says 'Type' but the lookup is the Value field.) This defines the enum's numeric value in generated TypeScript.","triggerScenarios":"Calling AddEnum with a slice of structs where the struct lacks an exported Value field (or the field exists but the reflector cannot access it).","commonSituations":"Feeding wails' typescriptify custom enum structs (e.g. additional system events enums) that define only Name/TSName but not Value, or where Value is unexported.","solutions":["Add an exported Value field to the enum struct (e.g. Value int)","Ensure the field name is exactly 'Value' and exported","Alternatively pass non-struct values that implement TSNamer"],"exampleFix":"// before\ntype Status struct{ TSName string }\nts.AddEnum([]Status{{\"Active\"}}) // panics: no Value field\n\n// after\ntype Status struct {\n    Value  int\n    TSName string\n}\nts.AddEnum([]Status{{0, \"Active\"}, {1, \"Inactive\"}})","handlingStrategy":"type-guard","validationCode":"// verify required struct shape before registering\nv := reflect.ValueOf(elements[0])\nif v.Kind() == reflect.Struct {\n    if _, ok := v.Type().FieldByName(\"Value\"); !ok {\n        return fmt.Errorf(\"enum struct %s needs exported Value field\", v.Type())\n    }\n}","typeGuard":"type enumElement interface{ getValue() int; getTSName() string } // marker implemented by your enum structs\n// plus compile-time check:\nvar _ = struct{ Value int; TSName string }{} // shape reminder for every enum struct","tryCatchPattern":null,"preventionTips":["Give every enum struct exported Value and TSName fields","Add a compile-time assertion type per enum to lock the shape"],"tags":["typescript","bindings","reflection","api-misuse","panic"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}