{"record":{"id":"036d915b3acd88ec","repo":"go-playground/validator","slug":"bad-field-type-t","errorCode":null,"errorMessage":"Bad field type %T","messagePattern":"Bad field type %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baked_in.go","lineNumber":1716,"sourceCode":"\n// isUrnRFC8141 is the validation function for validating if the current field's value is a valid URN as per RFC 8141.\nfunc isUrnRFC8141(fl FieldLevel) bool {\n\tfield := fl.Field()\n\n\tswitch field.Kind() {\n\tcase reflect.String:\n\n\t\tstr := field.String()\n\t\tif str == \"\" {\n\t\t\treturn false\n\t\t}\n\n\t\t_, match := urn.Parse([]byte(str), urn.WithParsingMode(urn.RFC8141Only))\n\n\t\treturn match\n\t}\n\n\tpanic(fmt.Sprintf(\"Bad field type %T\", field.Interface()))\n}\n\n// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.\nfunc isUrnRFC2141(fl FieldLevel) bool {\n\tfield := fl.Field()\n\n\tswitch field.Kind() {\n\tcase reflect.String:\n\n\t\tstr := field.String()\n\n\t\t_, match := urn.Parse([]byte(str))\n\n\t\treturn match\n\t}\n\n\tpanic(fmt.Sprintf(\"Bad field type %s\", field.Type()))\n}","sourceCodeStart":1698,"sourceCodeEnd":1734,"githubUrl":"https://github.com/go-playground/validator/blob/facf128d2eecf42bd4ff447adc961aa21bb64aed/baked_in.go#L1698-L1734","documentation":"The `urn_rfc8141` validator parses the field as a URN per RFC 8141 using the github.com/leodido/go-urn package. It only supports reflect.Kind String; for any other kind it panics with `Bad field type %T` (formatted with field.Interface(), so the dynamic Go type is shown). This is a programming-error panic: the tag is on a field that cannot hold a URN string.","triggerScenarios":"Tagging non-string fields with `validate:\"urn_rfc8141\"`, e.g. `Urn [32]byte`, `Identifier uuid.UUID`, `URN any`. The %T verb in the panic makes it identifiable: it prints e.g. `Bad field type [32]uint8`.","commonSituations":"Storing URNs in byte arrays fixed-size buffers from C interop or protobuf; identifier fields typed as uuid.UUID where the developer wanted a URN-format check; interface{} fields in generic config containers.","solutions":["Change the field type to string (or a named string type).","If the value is stored as bytes, add a string field or convert with string(b) and validate with Var.","For uuid.UUID-like types, either validate with the `uuid` tag on a string representation or write a custom validator.","Avoid `interface{}`-typed fields carrying tags; type them concretely as string."],"exampleFix":"// before\ntype Resource struct {\n\tURN [64]byte `validate:\"urn_rfc8141\"` // panics: Bad field type [64]uint8\n}\n\n// after\ntype Resource struct {\n\tURN string `validate:\"urn_rfc8141\"` // e.g. \"urn:isbn:0451450523\"\n}","handlingStrategy":"type-guard","validationCode":"s, ok := any(field).(string)\nif !ok {\n\treturn fmt.Errorf(\"urn_rfc8141 requires string, got %T\", field)\n}\nif _, match := urn.Parse([]byte(s), urn.WithParsingMode(urn.RFC8141Only)); !match {\n\treturn fmt.Errorf(\"not a valid RFC 8141 URN: %s\", s)\n}","typeGuard":"func asURNString(v any) (string, bool) {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.String { return \"\", false }\n\treturn rv.String(), true\n}","tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\terr = fmt.Errorf(\"urn_rfc8141 panic (non-string field): %v\", r)\n\t}\n}()","preventionTips":["Keep URNs in string fields; convert []byte buffers to string before validation","Do not put tags on interface{} fields","Use v.Var(string(data), \"urn_rfc8141\") for byte-slice values"],"tags":["go","validator","panic","reflection","urn","rfc8141"],"backgroundTag":"validator-bad-field-type-panic","analyzedSha":"facf128d2eecf42bd4ff447adc961aa21bb64aed","analyzedAt":"2026-09-02T10:19:04.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}