diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 261885d0772..381ab67c773 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -2979,6 +2979,9 @@ func InsertWorkspacePresetAndParameters(ctx context.Context, db database.Store, return nil }, nil) + if database.IsUniqueViolation(err, database.UniqueIndexUniquePresetName) { + return xerrors.Errorf("duplicate preset name, must be unique per template: %q", protoPreset.Name) + } if err != nil { return xerrors.Errorf("insert preset and parameters: %w", err) } diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go index f3d9c18f551..0e2a5ea8d35 100644 --- a/coderd/provisionerdserver/provisionerdserver_test.go +++ b/coderd/provisionerdserver/provisionerdserver_test.go @@ -4009,6 +4009,36 @@ func TestInsertWorkspacePresetsAndParameters(t *testing.T) { } }) } + + t.Run("duplicate preset names", func(t *testing.T) { + t.Parallel() + + ctx := testutil.Context(t, testutil.WaitLong) + logger := testutil.Logger(t) + db, ps := dbtestutil.NewDB(t) + org := dbgen.Organization(t, db, database.Organization{}) + user := dbgen.User(t, db, database.User{}) + job := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{ + Type: database.ProvisionerJobTypeWorkspaceBuild, + OrganizationID: org.ID, + }) + templateVersion := dbgen.TemplateVersion(t, db, database.TemplateVersion{ + JobID: job.ID, + OrganizationID: org.ID, + CreatedBy: user.ID, + }) + + err := provisionerdserver.InsertWorkspacePresetsAndParameters( + ctx, + logger, + db, + job.ID, + templateVersion.ID, + []*sdkproto.Preset{{Name: "daily-driver"}, {Name: "daily-driver"}}, + time.Now(), + ) + require.ErrorContains(t, err, `duplicate preset name, must be unique per template: "daily-driver"`) + }) } func TestInsertWorkspaceResource(t *testing.T) {