{"record":{"id":"2916f81ee3e5d63b","repo":"apache/beam","slug":"schema-type-must-be-struct-v","errorCode":null,"errorMessage":"schema type must be struct: %v","messagePattern":"schema type must be struct: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/io/bigqueryio/bigquery.go","lineNumber":222,"sourceCode":"\t}\n\n\tfor {\n\t\tval := reflect.New(f.Type.T).Interface() // val : *T\n\t\tif err := it.Next(val); err != nil {\n\t\t\tif err == iterator.Done {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\temit(reflect.ValueOf(val).Elem().Interface()) // emit(*val)\n\t}\n\treturn nil\n}\n\nfunc mustInferSchema(t reflect.Type) bigquery.Schema {\n\tif t.Kind() != reflect.Struct {\n\t\tpanic(fmt.Sprintf(\"schema type must be struct: %v\", t))\n\t}\n\n\tcheckTypeRegistered(t)\n\n\tschema, err := bigquery.InferSchema(reflect.Zero(t).Interface())\n\tif err != nil {\n\t\tpanic(errors.Wrapf(err, \"invalid schema type: %v\", t))\n\t}\n\treturn schema\n}\n\nfunc checkTypeRegistered(t reflect.Type) {\n\tt = reflectx.SkipPtr(t)\n\tkey, ok := runtime.TypeKey(t)\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"type %v must be a named type (not anonymous) for registration\", t))\n\t}\n","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/bigqueryio/bigquery.go#L204-L240","documentation":"mustInferSchema in bigqueryio panics when the Go type whose schema is being inferred for BigQuery IO is not a struct. bigquery.InferSchema only works on struct types (fields map to BigQuery columns), so any other kind (int, slice, map, pointer-to-non-struct, etc.) is rejected immediately. This is a programming-time contract violation, not a runtime data problem.","triggerScenarios":"Calling bigqueryio.Read(s, project, dataset, table, beam.Create(s, 42)) or bigqueryio.Write with a PCollection whose element type is not a named struct — e.g. a PCollection<string>, PCollection<int>, or a slice/map element type.","commonSituations":"Feeding a plain scalar PCollection (from TextIO or Create of literals) into bigquery.Write; passing a []byte or map element; accidentally dereferencing to a non-struct type; writing a pipeline where an upstream DoFn emits primitives instead of row structs.","solutions":["Define a named struct whose exported fields represent the BigQuery row and make the PCollection emit that struct.","Ensure the PCollection passed to Read/Write has element type a struct (check col.Type().Type().Kind() == reflect.Struct before calling).","If the data is not row-shaped, insert a beam.ParDo that wraps each element into the row struct before writing."],"exampleFix":"// before\nbigqueryio.Write(s, proj, ds, table, beam.Create(s, \"a\", \"b\"))\n\n// after\ntype Row struct {\n    Name string `bigquery:\"name\"`\n}\nbigqueryio.Write(s, proj, ds, table, beam.Create(s, Row{Name: \"a\"}, Row{Name: \"b\"}))","handlingStrategy":"validation","validationCode":"if col.Type().Type().Kind() != reflect.Struct {\n    return fmt.Errorf(\"bigqueryio requires a struct element type, got %v\", col.Type().Type())\n}","typeGuard":"func isStructElem(col beam.PCollection) bool {\n    return col.Type().Type().Kind() == reflect.Struct\n}","tryCatchPattern":"func safeWrite(s beam.Scope, args ...) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Fatalf(\"bigquery write setup failed: %v\", r)\n        }\n    }()\n    bigqueryio.Write(s, args...)\n}","preventionTips":["Always model BigQuery rows as named structs with exported fields.","Check col.Type().Type().Kind() == reflect.Struct before wiring IO.","Keep conversion DoFns close to the IO call so element types stay visible."],"tags":["go","bigquery","panic","type-mismatch"],"backgroundTag":"type-mismatch","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"}