micro/go-micro · error

model: key field %q not set

Error message

model: key field %q not set

What it means

The in-memory model's Create serializes the struct and extracts the value of the schema's key field to index the record. If that key field is empty (zero value) on the struct instance, the record has no identity to store under, so Create returns this error naming the schema's key field.

Source

Thrown at model/memory.go:64

	t := ResolveType(v)
	m.mu.RLock()
	s, ok := m.types[t]
	m.mu.RUnlock()
	if !ok {
		return nil, ErrNotRegistered
	}
	return s, nil
}

func (m *memoryModel) Create(ctx context.Context, v interface{}) error {
	schema, err := m.schema(v)
	if err != nil {
		return err
	}
	fields := StructToMap(schema, v)
	key := KeyValue(schema, v)
	if key == "" {
		return fmt.Errorf("model: key field %q not set", schema.Key)
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	tbl := m.tables[schema.Table]
	if _, exists := tbl[key]; exists {
		return ErrDuplicateKey
	}
	row := make(map[string]any, len(fields))
	for k, v := range fields {
		row[k] = v
	}
	tbl[key] = row
	return nil
}

func (m *memoryModel) Read(ctx context.Context, key string, v interface{}) error {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Set the key field before calling Create, e.g. v.ID = uuid.NewString().
  2. Configure the model schema to auto-generate keys if the library supports it.
  3. Ensure JSON/unmarshal defaults aren't dropping the ID field (check struct tags and input payload).
  4. Add a validation step in your service layer that rejects entities with empty IDs before persisting.

Example fix

// before
user := User{Name: "alice"}
err := store.Create(ctx, &user)

// after
user := User{ID: uuid.NewString(), Name: "alice"}
if user.ID == "" {
    return errors.New("id required")
}
err := store.Create(ctx, &user)
Defensive patterns

Strategy: validation

Validate before calling

func requireKey(v interface{}, key string) error {
    rv := reflect.ValueOf(v)
    if rv.Kind() == reflect.Pointer {
        rv = rv.Elem()
    }
    f := rv.FieldByName(key)
    if !f.IsValid() || f.IsZero() {
        return fmt.Errorf("key field %q must be set before Create", key)
    }
    return nil
}
if err := requireKey(&user, "ID"); err != nil {
    return err
}
err := store.Create(ctx, &user)

Try / catch

if err := store.Create(ctx, &user); err != nil {
    if strings.Contains(err.Error(), "key field") {
        return fmt.Errorf("%w: generate an ID before Create", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling memoryModel.Create(ctx, v) with a struct whose key field (schema.Key, e.g. an ID) is the zero value ("", 0, nil) and no auto-generation is configured.

Common situations: Inserting a new entity without first generating a UUID/ID, constructing records from unmarshaled payloads that omit the ID, or tests reusing structs without resetting/setting keys.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/cdc892080b88ed89. Report an issue: GitHub.