go-kratos/kratos · warning
already exists
Error message
%s already exists
What it means
proto.Add (used by kratos proto add / new for API templates) is create-only: it creates the target directory if missing, then refuses to overwrite an existing file with the same name. The error names the file that already exists under the target path.
Solutions
- Delete or rename the existing file, then re-run the command
- Choose a different proto file/service name for the new API
- If regenerating on purpose, script the delete step first — the tool never overwrites
Example fix
# before $ kratos proto add user/v1/user.proto # ERROR: user.proto already exists # after $ rm api/user/v1/user.proto $ kratos proto add user/v1/user.proto
Defensive patterns
Strategy: validation
Validate before calling
target := filepath.Join(wd, p.Path, p.Name)
if _, err := os.Stat(target); err == nil {
return fmt.Errorf("skip %s: already exists", p.Name)
}
// proceed with proto add Prevention
- Delete stale generated files before re-running generators
- Adopt unique proto file names per version directory
- Treat generators as create-only: remove-then-generate in a script
When it happens
Trigger: Calling the proto add path twice, or scaffolding an API file whose final path os.Stat finds already existing (p.Path/p.Name combination present on disk).
Common situations: Re-running generation after a partial failure; two services sharing the same proto file name; leftover files from a previous layout attempt.
Related errors
- 🚫 failed to get relative path
- 🚫 failed to parse `go.mod
- 🚫 go.mod don't exists in
- invalid formatting for map key
- no field path
AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16).
Data as JSON: /api/errors/18f841ce8219a36b.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/kratos/internal/proto/add/proto.go:37
// Generate generate a proto template.
func (p *Proto) Generate() error {
body, err := p.execute()
if err != nil {
return err
}
wd, err := os.Getwd()
if err != nil {
panic(err)
}
to := filepath.Join(wd, p.Path)
if _, err := os.Stat(to); os.IsNotExist(err) {
if err := os.MkdirAll(to, 0o700); err != nil {
return err
}
}
name := filepath.Join(to, p.Name)
if _, err := os.Stat(name); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", p.Name)
}
return os.WriteFile(name, body, 0o644)
}
View on GitHub (pinned to 668db92c2c)