ipfs/kubo · error
already have a datastore named %q
Error message
already have a datastore named %q
What it means
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.).
Source
Thrown at repo/fsrepo/datastores.go:69
func (spec DiskSpec) String() string {
return string(spec.Bytes())
}
var datastores map[string]ConfigFromMap
func init() {
datastores = map[string]ConfigFromMap{
"mount": MountDatastoreConfig,
"mem": MemDatastoreConfig,
"log": LogDatastoreConfig,
"measure": MeasureDatastoreConfig,
}
}
func AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error {
_, ok := datastores[name]
if ok {
return fmt.Errorf("already have a datastore named %q", name)
}
datastores[name] = dsc
return nil
}
// AnyDatastoreConfig returns a DatastoreConfig from a spec based on
// the "type" parameter.
func AnyDatastoreConfig(params map[string]any) (DatastoreConfig, error) {
which, ok := params["type"].(string)
if !ok {
return nil, fmt.Errorf("'type' field missing or not a string")
}
fun, ok := datastores[which]
if !ok {
return nil, fmt.Errorf("unknown datastore type: %s", which)
}
return fun(params)View on GitHub (pinned to 329838acdf)
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
Example fix
// before
func init() {
plugin.RegisterDatastore("flatfs", NewFlatfsConfig) // already have a datastore named "flatfs"
}
// after
func init() {
plugin.RegisterDatastore("example-flatfs", NewFlatfsConfig) // unique name
} Defensive patterns
Strategy: validation
Validate before calling
func canRegister(name string) bool {
_, exists := registeredDatastores[name]
return !exists
}
if !canRegister("example-flatfs") {
return fmt.Errorf("datastore name already taken; choose another")
} Try / catch
if err := AddDatastoreConfigHandler(name, ctor); err != nil {
if strings.HasPrefix(err.Error(), "already have a datastore named") {
log.Printf("skipping duplicate datastore registration for %s", name)
return nil // idempotent registration
}
return err
} Prevention
- 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
When it happens
Trigger: 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").
Common situations: 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.
Related errors
- creating datastore config for %s: %w
- 'type' field missing or not a string
- unknown datastore type: %s
- 'mounts' field is missing or not an array
- expected map for mountpoint
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/3b3330d4ea25f973.
Report an issue: GitHub.