{"record":{"id":"3b3330d4ea25f973","repo":"ipfs/kubo","slug":"already-have-a-datastore-named-q","errorCode":null,"errorMessage":"already have a datastore named %q","messagePattern":"already have a datastore named %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/fsrepo/datastores.go","lineNumber":69,"sourceCode":"func (spec DiskSpec) String() string {\n\treturn string(spec.Bytes())\n}\n\nvar datastores map[string]ConfigFromMap\n\nfunc init() {\n\tdatastores = map[string]ConfigFromMap{\n\t\t\"mount\":   MountDatastoreConfig,\n\t\t\"mem\":     MemDatastoreConfig,\n\t\t\"log\":     LogDatastoreConfig,\n\t\t\"measure\": MeasureDatastoreConfig,\n\t}\n}\n\nfunc AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error {\n\t_, ok := datastores[name]\n\tif ok {\n\t\treturn fmt.Errorf(\"already have a datastore named %q\", name)\n\t}\n\n\tdatastores[name] = dsc\n\treturn nil\n}\n\n// AnyDatastoreConfig returns a DatastoreConfig from a spec based on\n// the \"type\" parameter.\nfunc AnyDatastoreConfig(params map[string]any) (DatastoreConfig, error) {\n\twhich, ok := params[\"type\"].(string)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"'type' field missing or not a string\")\n\t}\n\tfun, ok := datastores[which]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown datastore type: %s\", which)\n\t}\n\treturn fun(params)","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/repo/fsrepo/datastores.go#L51-L87","documentation":"fsrepo keeps a global registry (datastores map[string]ConfigFromMap) mapping datastore type names to config constructors. AddDatastoreConfigHandler registers a new one and returns this error when a constructor is already registered under the same name. It guards against duplicate plugin registration and collisions with built-in datastore types (flatfs, badgerds, etc.).","triggerScenarios":"A datastore plugin calling AddDatastoreConfigHandler with a name already taken: loading two plugins that register the same datastore name, restarting/double-initializing the plugin loader in one process (loadDatastorePlugins run twice), or a plugin choosing a name identical to a built-in (\"flatfs\", \"badgerds\").","commonSituations":"Users installing a third-party datastore plugin that conflicts with another installed plugin or a built-in name; plugin directories containing duplicate/symlinked copies of the same plugin; kubo used as a library where makeNode or plugin injection runs more than once per process.","solutions":["Rename the plugin's datastore to a unique name (prefix it, e.g. \"myorg-flatfs\") and rebuild the plugin","Remove the duplicate plugin file from the plugins directory so only one registration happens","Ensure the plugin loader / AddDatastoreConfigHandler is invoked once per process (guard with sync.Once or init-time check)","If intentionally overriding, unregister or extend the registry first — but avoid shadowing built-in datastore names"],"exampleFix":"// before\nfunc init() {\n    plugin.RegisterDatastore(\"flatfs\", NewFlatfsConfig) // already have a datastore named \"flatfs\"\n}\n// after\nfunc init() {\n    plugin.RegisterDatastore(\"example-flatfs\", NewFlatfsConfig) // unique name\n}","handlingStrategy":"validation","validationCode":"func canRegister(name string) bool {\n    _, exists := registeredDatastores[name]\n    return !exists\n}\nif !canRegister(\"example-flatfs\") {\n    return fmt.Errorf(\"datastore name already taken; choose another\")\n}","typeGuard":null,"tryCatchPattern":"if err := AddDatastoreConfigHandler(name, ctor); err != nil {\n    if strings.HasPrefix(err.Error(), \"already have a datastore named\") {\n        log.Printf(\"skipping duplicate datastore registration for %s\", name)\n        return nil // idempotent registration\n    }\n    return err\n}","preventionTips":["Give plugin datastores unique, org-prefixed names that cannot collide with built-ins (flatfs, badgerds)","Guard plugin loading with sync.Once so handlers register exactly once per process","Deduplicate the plugins directory (no copies/symlinks of the same plugin)","Check the built-in datastore name list before choosing a plugin name"],"tags":["plugins","datastore","config","registration"],"backgroundTag":"duplicate-plugin-registration","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}