flipped-aurora/gin-vue-admin · error
存在同名CLI
Error message
存在同名CLI
What it means
CreateCli enforces unique CLI names: after the empty check it calls sysCliNameExists(ctx, name, 0), where 0 means "exclude no id" (full-table uniqueness for creation). If a record with the same trimmed name already exists, creation is rejected with this error. This prevents duplicate CLI identifiers that would be ambiguous to invoke.
Source
Thrown at server/plugin/ai/service/sys_cli.go:26
"github.com/flipped-aurora/gin-vue-admin/server/global"
sysModel "github.com/flipped-aurora/gin-vue-admin/server/model/system"
autoModel "github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model"
autoReq "github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model/request"
autoRes "github.com/flipped-aurora/gin-vue-admin/server/plugin/ai/model/response"
"gorm.io/gorm"
)
type cliService struct{}
func (s *cliService) CreateCli(ctx context.Context, req autoReq.CreateSysCliRequest) (autoModel.SysCli, error) {
name := strings.TrimSpace(req.Name)
if name == "" {
return autoModel.SysCli{}, errors.New("cli名称不能为空")
}
if exists, err := s.sysCliNameExists(ctx, name, 0); err != nil {
return autoModel.SysCli{}, err
} else if exists {
return autoModel.SysCli{}, errors.New("存在同名CLI")
}
entity := autoModel.SysCli{
Name: name,
Command: strings.TrimSpace(req.Command),
DisplayName: strings.TrimSpace(req.DisplayName),
Version: strings.TrimSpace(req.Version),
Description: strings.TrimSpace(req.Description),
Status: strings.TrimSpace(req.Status),
AuthMode: "jwt",
SkillName: strings.TrimSpace(req.SkillName),
SkillDescription: strings.TrimSpace(req.SkillDescription),
ScenariosJSON: req.ScenariosJSON, // JSON 原文不裁剪
}
applySysCliDefaults(&entity)
if err := global.GVA_DB.WithContext(ctx).Create(&entity).Error; err != nil {
return autoModel.SysCli{}, err
}
return entity, nilView on GitHub (pinned to 3136500ef3)
Solutions
- Use the update/edit endpoint for the existing CLI instead of creating a new one
- Choose a different, unique name for the new CLI
- Check the CLI list first to confirm whether the record already exists before creating
- Disable the submit button after first click to avoid duplicate submissions
Example fix
// before: create on every save
await createCli({ name: 'my-cli' })
// after: update when the record exists
if (existingCliId) {
await updateCli(existingCliId, { name: 'my-cli' })
} else {
await createCli({ name: 'my-cli' })
} Defensive patterns
Strategy: validation
Validate before calling
// before create, check uniqueness client-side when the list is available
if (cliList.some(c => c.name === name.trim())) {
throw new Error(`CLI "${name}" already exists — use update instead`)
} Try / catch
try {
await createCli({ name })
} catch (e) {
if (String(e.message).includes('存在同名CLI')) {
// switch the dialog to edit mode for the existing record
openEditForExisting(name)
} else { throw e }
} Prevention
- Search the existing CLI list before creating to avoid duplicates
- Debounce/disable the submit button to prevent double submissions
- Use the update endpoint to modify existing CLIs, not create
- Document that names are unique (post-trim) so users pick distinct names
When it happens
Trigger: Calling CreateCli with a name that already exists in the sys_cli table — e.g. resubmitting a form after a successful create, or two users/sessions creating the same CLI concurrently.
Common situations: Double-click/double-submit of the create form; importing or seeding CLIs that already exist; trying to "update" via the create endpoint; case or whitespace differences that trim to the same name.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/5134e59b15cf1a43.
Report an issue: GitHub.