flipped-aurora/gin-vue-admin · error

脚本已存在

Error message

脚本已存在

What it means

CreateScript checks os.Stat on <skillDir>/scripts/<fileName>; if the file already exists (stat succeeds) it returns "脚本已存在" instead of overwriting. The service never clobbers existing scripts.

Source

Thrown at server/service/system/sys_skills.go:284

func (s *SkillsService) CreateScript(_ context.Context, req request.SkillScriptCreateRequest) (string, string, error) {
	if !isSafeName(req.Skill) {
		return "", "", errors.New("技能名称不合法")
	}
	fileName, lang, err := buildScriptFileName(req.FileName, req.ScriptType)
	if err != nil {
		return "", "", err
	}
	if lang == "" {
		return "", "", errors.New("脚本类型不支持")
	}
	skillDir, err := s.ensureSkillDir(req.Tool, req.Skill)
	if err != nil {
		return "", "", err
	}
	filePath := filepath.Join(skillDir, "scripts", fileName)
	if _, err := os.Stat(filePath); err == nil {
		return "", "", errors.New("脚本已存在")
	}
	if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
		return "", "", err
	}
	content := scriptTemplate(lang)
	if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
		return "", "", err
	}
	return fileName, content, nil
}

func (s *SkillsService) GetScript(_ context.Context, req request.SkillFileRequest) (string, error) {
	return s.readSkillFile(req.Tool, req.Skill, "scripts", req.FileName)
}

func (s *SkillsService) SaveScript(_ context.Context, req request.SkillFileSaveRequest) error {
	return s.writeSkillFile(req.Tool, req.Skill, "scripts", req.FileName, req.Content)
}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Pick a different file name
  2. If you want to change the existing script, use the SaveScript API to overwrite its content instead of CreateScript
  3. Delete the existing script file first if it is no longer needed

Example fix

// before (fails: run.sh exists)
CreateScript({skill: "deploy", fileName: "run", scriptType: "sh"})
// after (overwrite content instead)
SaveScript({skill: "deploy", fileName: "run.sh", content: newContent})
Defensive patterns

Strategy: try-catch

Validate before calling

target := filepath.Join(skillDir, "scripts", fileName)
if _, err := os.Stat(target); err == nil { /* exists: switch to save/update flow */ }

Try / catch

err := svc.CreateScript(ctx, req)
if err != nil && err.Error() == "脚本已存在" {
    // fall back to SaveScript to overwrite content
    return svc.SaveScript(ctx, request.SkillFileSaveRequest{Tool: req.Tool, Skill: req.Skill, FileName: fileName, Content: newContent})
}
return err

Prevention

When it happens

Trigger: Calling CreateScript with a fileName whose normalized result (base + language extension) already exists in the skill's scripts/ directory, e.g. creating "run" with type sh when run.sh exists.

Common situations: Retrying a create after a previous success; creating a script whose name collides with an extension-stripped existing file; concurrent creation by two users; duplicate names in a synced skill copied across tools.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/15956340a5894b0a. Report an issue: GitHub.