From bd4af31f78024daeb512921a40cbf12d2bda31ce Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Wed, 26 Aug 2026 11:00:31 +0700 Subject: [PATCH] fix(coderd/provisionerdserver): clarify duplicate preset errors (#28530) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > 🤖 This PR was written by Coder Agents on behalf of Jake Howell. Template imports with duplicate preset names currently expose the underlying PostgreSQL unique constraint error. Translate that constraint violation into a clear validation message that identifies the duplicate preset name. image Closes https://github.com/coder/coder/issues/19270 --- .../provisionerdserver/provisionerdserver.go | 3 ++ .../provisionerdserver_test.go | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+) 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) {