Skip to content

fix(loader): replace panic with error handling in template loader#6825

Merged
dogancanbakir merged 2 commits intoprojectdiscovery:devfrom
bimakw:fix/replace-panic-with-error-handling
Mar 4, 2026
Merged

fix(loader): replace panic with error handling in template loader#6825
dogancanbakir merged 2 commits intoprojectdiscovery:devfrom
bimakw:fix/replace-panic-with-error-handling

Conversation

@bimakw
Copy link
Contributor

@bimakw bimakw commented Feb 4, 2026

Summary

Replace panic with proper error return in template loader when dialers are missing, allowing callers to handle the situation gracefully.

Changes

pkg/catalog/loader/loader.go

  • Modify LoadTemplatesWithTags signature: []*templates.Template([]*templates.Template, error)
  • Modify LoadTemplates signature: []*templates.Template([]*templates.Template, error)
  • Modify Load signature: voiderror
  • Replace panic("dialers with executionId...") with fmt.Errorf("dialers with executionId %s not found", ...)
  • Replace panic("could not create wait group") with fmt.Errorf("could not create wait group: %w", errWg)

Callers updated

  • internal/runner/lazy.go - Handle error from LoadTemplates
  • internal/runner/runner.go - Handle error from Load
  • internal/server/nuclei_sdk.go - Handle error from Load
  • lib/multi.go - Handle error from Load
  • lib/sdk.go - Handle error from Load
  • cmd/integration-test/library.go - Handle error from Load
  • pkg/protocols/common/automaticscan/util.go - Handle error from LoadTemplatesWithTags
  • pkg/catalog/loader/loader_bench_test.go - Update to handle two return values

Before/After

Before (panic):

panic: dialers with executionId abc123 not found

After (graceful error):

templates, err := store.LoadTemplates(templatesList)
if err != nil {
    // Error: "dialers with executionId abc123 not found"
    // Caller can handle gracefully
    return err
}

Test Plan

  • go build ./... passes
  • go vet ./... passes
  • go test ./pkg/catalog/loader/... passes
  • Existing tests continue to work

Fixes #6674

/claim #6674

Summary by CodeRabbit

  • Bug Fixes

    • Template-loading failures are now detected, wrapped (e.g., "could not load templates") and returned instead of being silently ignored.
    • Initialization paths now propagate load errors to callers, preventing proceed-on-failure scenarios.
    • Validation added to ensure exactly one template is selected; clear errors returned when none or multiple are found.
  • Tests

    • Tests and benchmarks updated to accommodate the revised template-loading behavior and error returns.
  • Style

    • Internal string construction updated to use direct formatted writes, preserving output while reducing intermediate allocations.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a35650c and a627889.

📒 Files selected for processing (9)
  • internal/runner/healthcheck.go
  • lib/sdk_private.go
  • pkg/fuzz/analyzers/time/time_delay.go
  • pkg/js/devtools/scrapefuncs/main.go
  • pkg/js/devtools/tsgen/cmd/tsgen/main.go
  • pkg/js/libs/mysql/mysql_private.go
  • pkg/protocols/headless/engine/rules.go
  • pkg/reporting/reporting.go
  • pkg/utils/utils.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/js/devtools/scrapefuncs/main.go

Walkthrough

Loader APIs now return errors; callers were updated to check and propagate those errors. Numerous sites also replaced fmt.Sprintf(...)+WriteString with direct fmt.Fprintf to string builders; tests/benchmarks adjusted for the new loader return signatures.

Changes

Cohort / File(s) Summary
Core Loader API
pkg/catalog/loader/loader.go
Changed Load(), LoadTemplates(...), and LoadTemplatesWithTags(...) to return errors; replaced panics with explicit error returns and added error propagation throughout loader logic.
Loader tests / benchmarks
pkg/catalog/loader/loader_bench_test.go
Updated calls to the new two-value return from LoadTemplates(...) (now discarding both return values where appropriate).
Load callsites (error handling added)
cmd/integration-test/library.go, internal/runner/runner.go, internal/server/nuclei_sdk.go, lib/multi.go, lib/sdk.go
Replaced ignored store.Load() calls with error checks and wrapped returns; callers now return on loader failures instead of continuing.
Runner — lazy auth template logic
internal/runner/lazy.go
Now handles loader errors, enforces exactly one template found (errors if none or >1), and propagates execution errors via existing error paths.
Protocol helper (template load error propagation)
pkg/protocols/common/automaticscan/util.go
Captures and returns wrapped errors from template loading instead of ignoring failures.
Formatting refactors — use fmt.Fprintf into builders
internal/runner/healthcheck.go, pkg/js/libs/ldap/utils.go, lib/sdk_private.go, pkg/fuzz/analyzers/time/time_delay.go, pkg/js/devtools/scrapefuncs/main.go, pkg/js/devtools/tsgen/cmd/tsgen/main.go, pkg/js/libs/mysql/mysql_private.go, pkg/protocols/headless/engine/rules.go, pkg/reporting/reporting.go, pkg/utils/utils.go
Replaced patterns of WriteString(fmt.Sprintf(...)) with fmt.Fprintf(&builder, ...) across many helpers and reporters; no behavioral changes, only formatting/alloc reduction.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through lines where silence grew,
Replaced the thud with errors true,
Templates now speak instead of fall,
I checked each call and patched the hall,
Tiny paws, a careful chew 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing panics with error handling in the template loader, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Replace panic with proper error return when dialers are missing,
allowing callers to handle the situation gracefully.

Changes:
- Modify LoadTemplatesWithTags to return ([]*templates.Template, error)
- Modify LoadTemplates to return ([]*templates.Template, error)
- Modify Load to return error
- Replace panic("dialers with executionId...") with fmt.Errorf
- Replace panic("could not create wait group") with fmt.Errorf
- Update all callers to handle the new error return

Callers updated:
- internal/runner/lazy.go
- internal/runner/runner.go
- internal/server/nuclei_sdk.go
- lib/multi.go
- lib/sdk.go
- cmd/integration-test/library.go
- pkg/protocols/common/automaticscan/util.go
- pkg/catalog/loader/loader_bench_test.go

Fixes projectdiscovery#6674
@bimakw bimakw force-pushed the fix/replace-panic-with-error-handling branch from 88458db to 75525ed Compare February 6, 2026 10:10
@bimakw
Copy link
Contributor Author

bimakw commented Feb 10, 2026

Hey, the integration test failures here are unrelated to this PR. The failing test interactsh-requests-mc-and.yaml is hitting a flaky external dependency -- the interactsh server (oast.site) is returning corrupted DNS data, so the scan gets 0 results instead of 1. This happens across all 3 OS targets.

I confirmed this by checking the fix/js-pool-context-starvation branch (run 21862152606, ran today) which has the exact same failures: interactsh-requests-mc-and.yaml on all 3 OS, plus py-interactsh.yaml and headless-basic.yaml. That branch has completely unrelated changes, so this is clearly an infra/external service issue, not something introduced by the panic-to-error-handling change here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/sdk.go`:
- Around line 113-115: The new loader error returned by e.store.Load() must be
propagated and not ignored: update callers that currently ignore
e.LoadAllTemplates() (notably the places using `_ = e.LoadAllTemplates()`) to
check and return or handle its error, and add guards before dereferencing
e.store (calls to e.store.Templates() and e.store.Workflows()) so they only run
when LoadAllTemplates succeeded; also ensure ExecuteCallbackWithCtx surfaces the
underlying load error instead of masking it by returning early or wrapping the
real error. Target the functions/methods that call e.LoadAllTemplates(), any
uses of e.store.Templates()/e.store.Workflows(), and ExecuteCallbackWithCtx to
propagate or guard against load failures.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75525ed and 99c2fad.

📒 Files selected for processing (2)
  • lib/sdk.go
  • pkg/protocols/common/automaticscan/util.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/protocols/common/automaticscan/util.go

Comment on lines +113 to +115
if err := e.store.Load(); err != nil {
return errkit.Wrapf(err, "Could not load templates: %s", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Propagate the new loader error; internal callers still drop it and can still crash.

Great change at Line 113-Line 115, but the new error is still ignored at Line 123, Line 131, and Line 258 (_ = e.LoadAllTemplates()). If loading fails before e.store is ready, subsequent e.store.Templates() / e.store.Workflows() dereferences can panic, and ExecuteCallbackWithCtx may mask the real failure.

Suggested fix (propagate/guard load failures)
 func (e *NucleiEngine) GetTemplates() []*templates.Template {
 	if !e.templatesLoaded {
-		_ = e.LoadAllTemplates()
+		if err := e.LoadAllTemplates(); err != nil {
+			return nil
+		}
 	}
+	if e.store == nil {
+		return nil
+	}
 	return e.store.Templates()
 }

 func (e *NucleiEngine) GetWorkflows() []*templates.Template {
 	if !e.templatesLoaded {
-		_ = e.LoadAllTemplates()
+		if err := e.LoadAllTemplates(); err != nil {
+			return nil
+		}
 	}
+	if e.store == nil {
+		return nil
+	}
 	return e.store.Workflows()
 }

 func (e *NucleiEngine) ExecuteCallbackWithCtx(ctx context.Context, callback ...func(event *output.ResultEvent)) error {
 	if !e.templatesLoaded {
-		_ = e.LoadAllTemplates()
+		if err := e.LoadAllTemplates(); err != nil {
+			return err
+		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/sdk.go` around lines 113 - 115, The new loader error returned by
e.store.Load() must be propagated and not ignored: update callers that currently
ignore e.LoadAllTemplates() (notably the places using `_ =
e.LoadAllTemplates()`) to check and return or handle its error, and add guards
before dereferencing e.store (calls to e.store.Templates() and
e.store.Workflows()) so they only run when LoadAllTemplates succeeded; also
ensure ExecuteCallbackWithCtx surfaces the underlying load error instead of
masking it by returning early or wrapping the real error. Target the
functions/methods that call e.LoadAllTemplates(), any uses of
e.store.Templates()/e.store.Workflows(), and ExecuteCallbackWithCtx to propagate
or guard against load failures.

@dogancanbakir dogancanbakir force-pushed the fix/replace-panic-with-error-handling branch from 6cb9a2d to 99c2fad Compare March 4, 2026 13:36
@neo-by-projectdiscovery-dev
Copy link

neo-by-projectdiscovery-dev bot commented Mar 4, 2026

Neo - PR Security Review

No security issues found

Highlights

  • Replaces panic() calls with proper error return values in template loader functions (LoadTemplatesWithTags, LoadTemplates, Load)
  • Updates all callers across the codebase to handle returned errors gracefully
  • Improves reliability by preventing panic-induced crashes when dialers are not initialized

Comment @pdneo help for available commands. · Open in Neo

@dogancanbakir dogancanbakir merged commit bde0272 into projectdiscovery:dev Mar 4, 2026
13 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace panic with error handling in template loader when dialers are missing

4 participants