{"record":{"id":"bff8549f0035595f","repo":"apache/beam","slug":"invalid-logical-type-bad-id-v-v","errorCode":null,"errorMessage":"invalid logical type, bad id: %v -> %v","messagePattern":"invalid logical type, bad id: (.+?) -> (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/schema/logicaltypes.go","lineNumber":99,"sourceCode":"\t\tidToType:        map[string]reflect.Type{},\n\t\tsyntheticToUser: map[reflect.Type]reflect.Type{},\n\n\t\tlogicalTypes:           map[string]LogicalType{},\n\t\tlogicalTypeIdentifiers: map[reflect.Type]string{},\n\t\tlogicalTypeProviders:   map[reflect.Type]LogicalTypeProvider{},\n\t}\n}\n\n// RegisterLogicalType a single logical type.\nfunc (r *Registry) RegisterLogicalType(lt LogicalType) {\n\t// Validates that the storage type has known handling.\n\tst := lt.StorageType()\n\t_, err := r.reflectTypeToFieldType(st)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"LogicalType[%v] has an invalid StorageType %v: %v\", lt.ID(), st, err))\n\t}\n\tif len(lt.ID()) == 0 {\n\t\tpanic(fmt.Sprintf(\"invalid logical type, bad id: %v -> %v\", lt.GoType(), lt.StorageType()))\n\t}\n\t// TODO add duplication checks.\n\tr.logicalTypeIdentifiers[lt.GoType()] = lt.ID()\n\tr.logicalTypes[lt.ID()] = lt\n}\n\n// RegisterLogicalTypeProvider allows registration of providers for interface types.\nfunc (r *Registry) RegisterLogicalTypeProvider(rt reflect.Type, ltp LogicalTypeProvider) {\n\tif rt.Kind() != reflect.Interface {\n\t\tpanic(fmt.Sprintf(\"Logical Types must be registered with interface types. %v is not an interface type.\", rt))\n\t}\n\tif rt.NumMethod() == 0 {\n\t\tpanic(fmt.Sprintf(\"Logical Types may not be registered with empty interface types. %v has no methods.\", rt))\n\t}\n\tr.logicalTypeProviders[rt] = ltp\n\tr.logicalTypeInterfaces = append(r.logicalTypeInterfaces, rt)\n}\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/schema/logicaltypes.go#L81-L117","documentation":"RegisterLogicalType requires a non-empty logical type identifier (lt.ID()), which is used as the schema protocol name for the type. An empty ID would make the type unreferenceable in the wire schema, so registration panics.","triggerScenarios":"Registering a LogicalType whose ID() method returns an empty string, via RegisterLogicalType, registerType, or preRegLogicalTypes.","commonSituations":"Custom LogicalType implementations with placeholder or unimplemented ID() methods; empty constant identifiers after refactoring.","solutions":["Implement ID() to return a unique, stable non-empty string identifier","Add a guard in your LogicalType constructor to fail early on empty IDs","Check for refactoring mistakes where the ID constant became an empty string"],"exampleFix":"// before\nfunc (t myLT) ID() string { return \"\" }\n// after\nfunc (t myLT) ID() string { return \"mycompany.myLogicalType\" }","handlingStrategy":"validation","validationCode":"if len(lt.ID()) == 0 { return errors.New(\"logical type ID must be non-empty\") }\nr.RegisterLogicalType(lt)","typeGuard":null,"tryCatchPattern":"defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"register logical type: %v\", r) } }()","preventionTips":["Use reverse-DNS style stable identifiers","Add constructor checks rejecting empty IDs","Unit test ID() output"],"tags":["go","apache-beam","schema","logical-type","panic"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}