projectdiscovery/nuclei · error
multiple templates found for path: %s
Error message
multiple templates found for path: %s
What it means
LoadTemplates returned more than one template for the dynamic secret's single path (internal/runner/lazy.go:78); the callback requires exactly one template to execute for a dynamic secret, so ambiguity is an error. This occurs when TemplatePath is a directory or a glob-like value that expands to multiple template files.
Source
Thrown at internal/runner/lazy.go:78
store, err := loader.New(cfg)
if err != nil {
return nil, errkit.Wrap(err, "failed to initialize dynamic auth templates store")
}
return store, nil
}
// GetLazyAuthFetchCallback returns a lazy fetch callback for auth secrets
func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret {
return func(d *authx.Dynamic) error {
tmpls, err := opts.TemplateStore.LoadTemplates([]string{d.TemplatePath})
if err != nil {
return fmt.Errorf("failed to load templates: %w", err)
}
if len(tmpls) == 0 {
return fmt.Errorf("%w for path: %s", disk.ErrNoTemplatesFound, d.TemplatePath)
}
if len(tmpls) > 1 {
return fmt.Errorf("multiple templates found for path: %s", d.TemplatePath)
}
data := map[string]interface{}{}
tmpl := tmpls[0]
// add args to tmpl here
vars := map[string]interface{}{}
mainCtx := context.Background()
ctx := scan.NewScanContext(mainCtx, contextargs.NewWithInput(mainCtx, d.Input))
cliVars := map[string]interface{}{}
if opts.ExecOpts.Options != nil {
// gets variables passed from cli -v and -env-vars
cliVars = generators.BuildPayloadFromOptions(opts.ExecOpts.Options)
}
for _, v := range d.Variables {
// Check if the template has any env variables and expand them
if strings.HasPrefix(v.Value, "$") {
env.ExpandWithEnv(&v.Value)View on GitHub (pinned to 265b3a3dec)
Solutions
- Set TemplatePath to one specific .yaml template file
- Remove glob/wildcard characters from the path
- Split multi-template auth logic so each dynamic secret maps to exactly one template
Example fix
# before template-path: auth/ # after template-path: auth/get-session.yaml
Defensive patterns
Strategy: validation
Validate before calling
// ensure the path resolves to exactly one template file
matches, _ := filepath.Glob(d.TemplatePath)
if strings.ContainsAny(d.TemplatePath, "*?[") || len(matches) != 1 {
return fmt.Errorf("template path %s must be one specific file", d.TemplatePath)
} Try / catch
if len(tmpls) > 1 {
return fmt.Errorf("path %s matched %d templates; point at a single .yaml file", d.TemplatePath, len(tmpls))
} Prevention
- Use concrete file paths, never directories or globs, for dynamic secrets
- One auth template per dynamic secret
- Document the expected shape of template-path in config examples
When it happens
Trigger: TemplatePath pointing at a directory containing several templates; wildcard characters in the path expanded by the loader; a file path that matches multiple indexed entries.
Common situations: Pointing dynamic secrets at a folder of auth templates instead of one file; copy-pasted configs that use glob patterns.
Related errors
- %w for path: %s
- failed to load templates: %w
- no extracted values found for template: %s
- Invalid protocol type: {valueToMap}
- invalid workflow with no templates or tags
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/ddab72b389f84e3c.
Report an issue: GitHub.