ipfs/kubo · error

'child' field is missing or not a map

Error message

'child' field is missing or not a map

What it means

LogDatastoreConfig wraps another datastore for event logging, and that wrapped datastore must be given as a nested spec under params["child"]. The error is thrown when "child" is missing or not a map[string]any, since a child DatastoreConfig cannot be constructed without it.

Source

Thrown at repo/fsrepo/datastores.go:189

func (c *memDatastoreConfig) DiskSpec() DiskSpec {
	return nil
}

func (c *memDatastoreConfig) Create(string) (repo.Datastore, error) {
	return dssync.MutexWrap(ds.NewMapDatastore()), nil
}

type logDatastoreConfig struct {
	child DatastoreConfig
	name  string
}

// LogDatastoreConfig returns a log DatastoreConfig from a spec.
func LogDatastoreConfig(params map[string]any) (DatastoreConfig, error) {
	childField, ok := params["child"].(map[string]any)
	if !ok {
		return nil, fmt.Errorf("'child' field is missing or not a map")
	}
	child, err := AnyDatastoreConfig(childField)
	if err != nil {
		return nil, err
	}
	name, ok := params["name"].(string)
	if !ok {
		return nil, fmt.Errorf("'name' field was missing or not a string")
	}
	return &logDatastoreConfig{child, name}, nil
}

func (c *logDatastoreConfig) Create(path string) (repo.Datastore, error) {
	child, err := c.child.Create(path)
	if err != nil {
		return nil, err
	}
	return ds.NewLogDatastore(child, c.name), nil

View on GitHub (pinned to 329838acdf)

Solutions

  1. Add a "child" key containing a full nested datastore spec map (with its own "type" and options)
  2. If the child was passed as a JSON string, unmarshal it into map[string]any first
  3. Move any top-level child datastore fields into the nested child object

Example fix

// before
spec := map[string]any{"type": "log", "name": "dslog"}
// after
spec := map[string]any{"type": "log", "name": "dslog", "child": map[string]any{"type": "flatfs", "path": "blocks"}}
Defensive patterns

Strategy: validation

Validate before calling

c, ok := params["child"].(map[string]any)
if !ok { /* add nested child spec before calling */ }

Type guard

func childSpec(params map[string]any) (map[string]any, bool) {
	c, ok := params["child"].(map[string]any)
	return c, ok
}

Try / catch

ds, err := fsrepo.LogDatastoreConfig(spec)
if err != nil {
	if strings.Contains(err.Error(), "'child' field") {
		return fmt.Errorf("log spec requires nested child: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling LogDatastoreConfig(params) with no "child" key, or where params["child"] is a string, bool, or already-constructed struct instead of a nested spec map.

Common situations: Spec of type "log" written without the nested child datastore; child spec supplied as a JSON string instead of an object; someone inlined the child fields at the top level instead of nesting them.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/27965e1c2485ba10. Report an issue: GitHub.