kgretzky/evilginx2 · error
js_inject: missing `trigger_domains` field
Error message
js_inject: missing `trigger_domains` field
What it means
Each entry in the `js_inject` list must define `trigger_domains`, the hosts on which the injected script runs. The parsed entry's `trigger_domains` field was nil, so phishlet validation fails before p.addJsInject would be reached. This ensures every script injection has at least one target host.
Source
Thrown at core/phishlet.go:469
return fmt.Errorf("sub_filters: missing `search` field")
}
if sf.Replace == nil {
return fmt.Errorf("sub_filters: missing `replace` field")
}
if sf.WithParams == nil {
sf.WithParams = &[]string{}
}
for n := range *sf.Mimes {
(*sf.Mimes)[n] = p.paramVal((*sf.Mimes)[n])
}
p.addSubFilter(p.paramVal(*sf.Hostname), p.paramVal(*sf.Sub), p.paramVal(*sf.Domain), *sf.Mimes, p.paramVal(*sf.Search), p.paramVal(*sf.Replace), sf.RedirectOnly, *sf.WithParams)
}
}
if fp.JsInject != nil {
for _, js := range *fp.JsInject {
if js.TriggerDomains == nil {
return fmt.Errorf("js_inject: missing `trigger_domains` field")
}
if js.TriggerPaths == nil {
return fmt.Errorf("js_inject: missing `trigger_paths` field")
}
if js.Script == nil {
return fmt.Errorf("js_inject: missing `script` field")
}
for n := range *js.TriggerDomains {
(*js.TriggerDomains)[n] = p.paramVal((*js.TriggerDomains)[n])
}
for n := range *js.TriggerPaths {
(*js.TriggerPaths)[n] = p.paramVal((*js.TriggerPaths)[n])
}
err := p.addJsInject(*js.TriggerDomains, *js.TriggerPaths, js.TriggerParams, p.paramVal(*js.Script))
if err != nil {
return err
}
}View on GitHub (pinned to 4c0988a1d9)
Solutions
- Add `trigger_domains: ['<hostname>']` (e.g. `trigger_domains: ['auth.example.com']`) to the js_inject entry
- Use the YAML list syntax since the code ranges over the slice later
- Reload and continue with the next reported field (trigger_paths, script)
Example fix
// before
js_inject:
- trigger_paths: ['/login']
script: 'alert(1)'
// after
js_inject:
- trigger_domains: ['auth.example.com']
trigger_paths: ['/login']
script: 'alert(1)' Defensive patterns
Strategy: validation
Validate before calling
for i, js in enumerate(cfg.get('js_inject') or []):
td = js.get('trigger_domains')
if not isinstance(td, list) or len(td) == 0:
raise ValueError(f"js_inject[{i}]: missing `trigger_domains` field") Type guard
func validJsInject(js JsInject) bool { return js.TriggerDomains != nil } Prevention
- Never write a js_inject entry without trigger_domains — there is no 'all domains' default
- Use plural `trigger_domains` (distinct from sub_filters' `triggers_on`)
- Validate the whole phishlet before a live session
When it happens
Trigger: A `js_inject:` entry in the phishlet YAML omits `trigger_domains:`; core/phishlet.go's `if js.TriggerDomains == nil` check fires while iterating fp.JsInject.
Common situations: Adding a js_inject block with only `script:`; copying a sub_filters-style entry whose field names differ; typo like `trigger_domain:` (singular).
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- js_inject: missing `trigger_paths` field
- js_inject: missing `script` field
- sub_filters: missing `domain` field
- sub_filters: missing `mimes` field
- sub_filters: missing `search` field
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/5588d0d14a302c11.
Report an issue: GitHub.