projectdiscovery/nuclei · error

%w for path: %s

Error message

%w for path: %s

What it means

LoadTemplates returned zero templates for the dynamic secret's path (internal/runner/lazy.go:75); the shared disk.ErrNoTemplatesFound ('no templates found') is wrapped with the offending path. The path resolved but matched nothing loadable as a template: nonexistent file, non-template file, or content excluded by the loader. The error text names the exact path that came up empty.

Source

Thrown at internal/runner/lazy.go:75

	opts.IncludeConditions = nil
	cfg := loader.NewConfig(opts, catalog, execOpts)
	cfg.StoreId = loader.AuthStoreId
	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 {

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Verify the exact path named in the error exists (`ls -l <TemplatePath>`)
  2. Correct TemplatePath in the dynamic secrets configuration
  3. Ensure the file is a real nuclei template (id, info, protocol sections)
  4. Lint secrets configs in CI so paths cannot drift from the templates

Example fix

# before (secrets file)
- id: session
  dynamic:
    template-path: auth/get-session-v1.yaml

# after
- id: session
  dynamic:
    template-path: auth/get-session-v2.yaml
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(d.TemplatePath); err != nil || fi.IsDir() {
    return fmt.Errorf("dynamic secret path %s does not point at a template file", d.TemplatePath)
}

Try / catch

if len(tmpls) == 0 {
    return fmt.Errorf("no template at %s — check the path in the secrets config", d.TemplatePath)
}

Prevention

When it happens

Trigger: A dynamic-secrets entry with a stale or wrong TemplatePath; the template deleted/moved after the secrets config was written; the file existing but not recognized as a nuclei template.

Common situations: Renaming or relocating auth templates without updating the secrets config; environment-specific paths baked into shared configs; empty files left by failed git checkouts.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/285765c5bce84179. Report an issue: GitHub.