{"record":{"id":"6333defb10788544","repo":"apache/beam","slug":"scheme-v-already-registered","errorCode":null,"errorMessage":"scheme %v already registered","messagePattern":"scheme (.+?) already registered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/filesystem/filesystem.go","lineNumber":52,"sourceCode":")\n\nvar registry = make(map[string]func(context.Context) Interface)\n\n// wellKnownSchemeImportPaths is used for delivering useful error messages when a\n// scheme is not found.\nvar wellKnownSchemeImportPaths = map[string]string{\n\t\"memfs\":   \"github.com/apache/beam/sdks/v2/go/pkg/beam/io/filesystem/memfs\",\n\t\"default\": \"github.com/apache/beam/sdks/v2/go/pkg/beam/io/filesystem/local\",\n\t\"gs\":      \"github.com/apache/beam/sdks/v2/go/pkg/beam/io/filesystem/gcs\",\n\t\"s3\":      \"github.com/apache/beam/sdks/v2/go/pkg/beam/io/filesystem/s3\",\n}\n\n// Register registers a file system backend under the given scheme.  For\n// example, \"hdfs\" would be registered a HFDS file system and HDFS paths used\n// transparently.\nfunc Register(scheme string, fs func(context.Context) Interface) {\n\tif _, ok := registry[scheme]; ok {\n\t\tpanic(fmt.Sprintf(\"scheme %v already registered\", scheme))\n\t}\n\tregistry[scheme] = fs\n}\n\n// New returns a new Interface for the given file path's scheme.\nfunc New(ctx context.Context, path string) (Interface, error) {\n\tscheme := getScheme(path)\n\tmkfs, ok := registry[scheme]\n\tif !ok {\n\t\treturn nil, errorForMissingScheme(scheme, path)\n\t}\n\treturn mkfs(ctx), nil\n}\n\nfunc errorForMissingScheme(scheme, path string) error {\n\tmessageSuffix := \"\"\n\tif suggestedImportPath, ok := wellKnownSchemeImportPaths[scheme]; ok {\n\t\tmessageSuffix = fmt.Sprintf(\": Consider adding the following import to your program to register an implementation for %q:\\n  import _ %q\", scheme, suggestedImportPath)","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/filesystem/filesystem.go#L34-L70","documentation":"filesystem.Register panics when the same URL scheme (e.g. \"gs\", \"s3\", \"hdfs\") is registered more than once. The package keeps a global scheme->factory registry and treats a duplicate registration as an initialization bug that could silently swap filesystem implementations.","triggerScenarios":"Calling filesystem.Register(\"s3\", myFs) twice in the same process — e.g. in two init() functions across packages, or in a library that users import alongside a package that registers the same scheme.","commonSituations":"Two vendored/internal packages both registering the same scheme; copy-pasted init() registration in a test helper and production package; dynamically calling Register inside a function that can run multiple times (tests, benchmarks, repeated setup).","solutions":["Remove the duplicate filesystem.Register call, keeping a single registration per scheme.","Move registration into an init() of exactly one package so it runs once per process.","If dynamic registration is needed, guard with your own sync.Once or check the registry first.","In tests, register the scheme once in TestMain rather than in each benchmark/test function."],"exampleFix":"// before\nfunc setup() { filesystem.Register(\"s3\", newS3FS) } // called per test\n\n// after\nvar once sync.Once\nfunc setup() {\n    once.Do(func() { filesystem.Register(\"s3\", newS3FS) })\n}","handlingStrategy":"validation","validationCode":"if _, already := filesystem.DefaultRegistry(); already {\n    // skip re-registration\n}","typeGuard":null,"tryCatchPattern":"var registerOnce sync.Once\nfunc registerFS(scheme string, fs func(context.Context) filesystem.Interface) {\n    registerOnce.Do(func() {\n        defer func() {\n            if r := recover(); r != nil {\n                log.Printf(\"filesystem register skipped: %v\", r)\n            }\n        }()\n        filesystem.Register(scheme, fs)\n    })\n}","preventionTips":["Register each scheme exactly once, in init() of one package.","Wrap Register in sync.Once when setup may run repeatedly.","Audit vendored packages for conflicting scheme registrations."],"tags":["go","filesystem","panic","duplicate-registration"],"backgroundTag":"invalid-state-transition","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"}