micro/go-micro · error
model/postgres: create: %w
Error message
model/postgres: create: %w
What it means
Create executes an INSERT built from the schema and values. Duplicate-key/unique-constraint violations are translated to model.ErrDuplicateKey; any other INSERT failure is wrapped as "model/postgres: create" with the underlying driver error. So this error means the insert failed for a reason other than a duplicate key.
Source
Thrown at model/postgres/postgres.go:106
return nil, model.ErrNotRegistered
}
return s, nil
}
func (d *postgresModel) Create(ctx context.Context, v interface{}) error {
schema, err := d.schema(v)
if err != nil {
return err
}
fields := model.StructToMap(schema, v)
cols, placeholders, values := buildInsert(schema, fields)
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", quoteIdent(schema.Table), cols, placeholders)
_, err = d.db.ExecContext(ctx, query, values...)
if err != nil {
if strings.Contains(err.Error(), "duplicate key") || strings.Contains(err.Error(), "unique constraint") {
return model.ErrDuplicateKey
}
return fmt.Errorf("model/postgres: create: %w", err)
}
return nil
}
func (d *postgresModel) Read(ctx context.Context, key string, v interface{}) error {
schema, err := d.schema(v)
if err != nil {
return err
}
cols := columnList(schema)
query := fmt.Sprintf("SELECT %s FROM %s WHERE %s = $1", cols, quoteIdent(schema.Table), quoteIdent(schema.Key))
row := d.db.QueryRowContext(ctx, query, key)
fields, err := scanRow(schema, row)
if err != nil {
return err
}
model.MapToStruct(schema, fields, v)
return nilView on GitHub (pinned to 24529f1404)
Solutions
- Unwrap the error to read the underlying Postgres message — it names the column/constraint at fault.
- Align the model schema with the actual table (run migrations) so columns and types match.
- Ensure required (NOT NULL) fields, including the key, are set on the struct before Create.
- Check connectivity/credentials if the cause is a connection or permission error.
- Handle model.ErrDuplicateKey separately if duplicates are expected business cases.
Example fix
// before
if err := store.Create(ctx, &user); err != nil {
return err // opaque
}
// after
if err := store.Create(ctx, &user); err != nil {
if errors.Is(err, model.ErrDuplicateKey) {
return ErrEmailTaken
}
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
log.Printf("insert failed: %s (column %s)", pgErr.Message, pgErr.ColumnName)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate NOT NULL and key fields before Create
func insertable(v interface{}, required []string) error {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Pointer {
rv = rv.Elem()
}
for _, name := range required {
if f := rv.FieldByName(name); !f.IsValid() || f.IsZero() {
return fmt.Errorf("field %q required before insert", name)
}
}
return nil
} Try / catch
if err := store.Create(ctx, &user); err != nil {
switch {
case errors.Is(err, model.ErrDuplicateKey):
return ErrAlreadyExists
default:
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
log.Printf("create failed [%s]: %s", pgErr.Code, pgErr.Message)
}
return fmt.Errorf("create: %w", err)
}
} Prevention
- Keep the model schema and DB migrations in sync to avoid column/type drift.
- Validate required and unique fields in the service layer before Create.
- Translate driver errors (pgconn.PgError) into domain errors at one boundary.
- Use connection pooling with health checks to reduce transient connection failures.
When it happens
Trigger: Calling postgresModel.Create(ctx, v) when the INSERT fails due to a NOT NULL violation, type mismatch, missing column (schema/table drift), connection drop, permission denial, or invalid values (e.g. malformed JSON/UUID strings).
Common situations: Schema changed in the DB but the model wasn't updated (or vice versa), inserting nil into NOT NULL columns, wrong data types from unmarshaled payloads, transient network failures to Postgres.
Related errors
- model/postgres: update: %w
- Couldn't create table
- Couldn't insert record ${key}
- Database connection not initialized
- unsupported statement
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/b05d9cdfc4cde57c.
Report an issue: GitHub.