{"record":{"id":"a52beee49329c360","repo":"kgretzky/evilginx2","slug":"phishlet-s-already-exists","errorCode":null,"errorMessage":"phishlet '%s' already exists","messagePattern":"phishlet '(.+?)' already exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/config.go","lineNumber":571,"sourceCode":"\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Config) AddPhishlet(site string, pl *Phishlet) {\n\tc.phishletNames = append(c.phishletNames, site)\n\tc.phishlets[site] = pl\n\tc.VerifyPhishlets()\n}\n\nfunc (c *Config) AddSubPhishlet(site string, parent_site string, customParams map[string]string) error {\n\tpl, err := c.GetPhishlet(parent_site)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = c.GetPhishlet(site)\n\tif err == nil {\n\t\treturn fmt.Errorf(\"phishlet '%s' already exists\", site)\n\t}\n\tsub_pl, err := NewPhishlet(site, pl.Path, &customParams, c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsub_pl.ParentName = parent_site\n\n\tc.phishletNames = append(c.phishletNames, site)\n\tc.phishlets[site] = sub_pl\n\tc.VerifyPhishlets()\n\n\treturn nil\n}\n\nfunc (c *Config) DeleteSubPhishlet(site string) error {\n\tpl, err := c.GetPhishlet(site)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":553,"sourceCodeEnd":589,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/config.go#L553-L589","documentation":"CreatePhishlet (child creation from a parent site) throws this when a phishlet with the requested new name already exists in the config. The check is GetPhishlet(site) succeeding, meaning the name is taken, so creation is aborted to avoid overwriting existing phishlet configuration.","triggerScenarios":"Calling phishlet creation with a site name that already exists — e.g. running 'phishlets create mysite o365 ...' twice, or re-running an idempotent-looking setup script that doesn't check for prior creation, or colliding with a loaded template phishlet of the same name.","commonSituations":"Re-running provisioning scripts after a partial failure; two operators creating the same child name; name collision with a built-in/template phishlet; migration scripts re-importing phishlet definitions.","solutions":["Choose a different, unique child phishlet name for the create call","If the existing phishlet should be replaced, delete it first (phishlets delete <name>) then create again","If it already exists with the right params, skip creation and just enable/configure the existing phishlet","Make scripts idempotent: check GetPhishlet/list output before calling create"],"exampleFix":"// console\n// before\nphishlets create o365-corp o365 hostname corp.example.com   # second run: already exists\n// after\nphishlets delete o365-corp\nphishlets create o365-corp o365 hostname corp.example.com","handlingStrategy":"try-catch","validationCode":"// before creating\nif _, err := c.GetPhishlet(site); err == nil {\n    return fmt.Errorf(\"phishlet %s exists; pick another name or delete it first\", site)\n}\nc.CreatePhishlet(site, parentSite, params, true)","typeGuard":null,"tryCatchPattern":"err := c.CreatePhishlet(site, parentSite, customParams, true)\nif err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        log.Printf(\"phishlet %s exists — reuse it or 'phishlets delete %s' first\", site, site)\n        return nil // treat as success in idempotent scripts\n    }\n    return err\n}","preventionTips":["Make provisioning scripts idempotent: check existence before create","Use unique child names (e.g. suffix with environment/owner)","Delete or rename stale phishlets before re-creating","Avoid names colliding with built-in/template phishlet names"],"tags":["configuration","phishlet","duplicate"],"backgroundTag":"duplicate-resource-name","analyzedSha":"4c0988a1d9db4d172a185e979a38bfd0efdb5830","analyzedAt":"2026-09-05T19:23:07.238Z","contentChangedAt":"2026-09-05T19:23:07.238Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}