{"record":{"id":"63681248ce05eebf","repo":"apache/beam","slug":"reconciling-for-fromtype","errorCode":null,"errorMessage":"reconciling for FromType","messagePattern":"reconciling for FromType","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go","lineNumber":322,"sourceCode":"func (r *Registry) addToMaps(synth, ut reflect.Type) {\n\tsynth = reflectx.SkipPtr(synth)\n\tut = reflectx.SkipPtr(ut)\n\t// empty types have no value for lookups.\n\tif synth != emptyStructType {\n\t\tr.syntheticToUser[synth] = ut\n\t\tr.syntheticToUser[reflect.PtrTo(synth)] = reflect.PtrTo(ut)\n\t}\n\tif ut != emptyStructType {\n\t\tr.syntheticToUser[ut] = ut\n\t\tr.syntheticToUser[reflect.PtrTo(ut)] = reflect.PtrTo(ut)\n\t}\n}\n\n// FromType returns a Beam Schema of the passed in type.\n// Returns an error if the type cannot be converted to a Schema.\nfunc (r *Registry) FromType(ot reflect.Type) (*pipepb.Schema, error) {\n\tif err := r.reconcileRegistrations(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"reconciling for FromType\")\n\t}\n\tif reflectx.SkipPtr(ot).Kind() != reflect.Struct {\n\t\treturn nil, errors.Errorf(\"cannot convert %v to schema. FromType only converts structs to schemas\", ot)\n\t}\n\treturn r.fromType(ot)\n}\n\nfunc (r *Registry) logicalTypeToFieldType(t reflect.Type) (*pipepb.FieldType, string, error) {\n\t// Check if a logical type was registered that matches this struct type directly\n\t// and if so, extract the schema from it for use.\n\tif lID, ok := r.logicalTypeIdentifiers[t]; ok {\n\t\tlt := r.logicalTypes[lID]\n\t\tftype, err := r.reflectTypeToFieldType(lt.StorageType())\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrapf(err, \"unable to convert LogicalType[%v]'s storage type %v for Go type of %v to a schema\", lID, lt.StorageType(), lt.GoType())\n\t\t}\n\t\treturn ftype, lID, nil\n\t}","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go#L304-L340","documentation":"Registry.FromType wraps any error returned by reconcileRegistrations with this message before returning. reconcileRegistrations brings lazily-queued user type and logical type registrations into the registry before conversion; if that internal synchronization fails, FromType cannot proceed. The root cause is in the wrapped error, not in FromType's input type.","triggerScenarios":"Calling Registry.FromType(t) when reconcileRegistrations fails — i.e. an error occurs while processing pending registrations (registerType recursion over queued types, or conversion inside reconciliation).","commonSituations":"Registering a user type whose struct contains an unconvertible field, then calling FromType; failures during the first schema conversion of a lazily-registered type when building a pipeline graph.","solutions":["Inspect the wrapped inner error for the actual registration failure.","Fix the type whose registration failed (usually an unsupported field kind inside a registered struct).","Register problematic types eagerly and validate their conversion at startup rather than lazily.","Unwrap the error chain to the root cause before debugging."],"exampleFix":"// before\nschm, err := reg.FromType(reflect.TypeOf(MyRow{})) // opaque wrapper\n// after\nif err != nil {\n    for errors.Unwrap(err) != nil { err = errors.Unwrap(err) }\n    log.Fatalf(\"root cause: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"if err := reg.reconcileRegistrations(); err != nil { return fmt.Errorf(\"reconcile failed: %w\", err) }","typeGuard":null,"tryCatchPattern":"schm, err := reg.FromType(reflect.TypeOf(MyRow{}))\nif err != nil {\n    return fmt.Errorf(\"FromType: %w\", err) // log full chain to find root cause\n}","preventionTips":["Eagerly register all user types at init so reconciliation is trivial.","Test schema conversion in unit tests before deploying pipelines.","Keep registrations out of concurrent code paths.","Log wrapped error chains fully to see the root cause."],"tags":["go","schema","registry","initialization"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}