Skip to content

fix: restore unreachable no-default-class error in load_plugin - #2011

Open
manunicholasjacob wants to merge 1 commit into
NVIDIA:mainfrom
manunicholasjacob:fix/plugins-default-class
Open

fix: restore unreachable no-default-class error in load_plugin#2011
manunicholasjacob wants to merge 1 commit into
NVIDIA:mainfrom
manunicholasjacob:fix/plugins-default-class

Conversation

@manunicholasjacob

Copy link
Copy Markdown
Contributor

What this changes

load_plugin() reads generator_mod.DEFAULT_CLASS directly when a plugin is
specified as category.module. If the module does not define that attribute,
the attribute access raises AttributeError, so the else branch below it
cannot be reached:

if generator_mod.DEFAULT_CLASS:
    plugin_class_name = generator_mod.DEFAULT_CLASS
else:
    raise ValueError(
        f"module {module_name} has no default class; pass module.ClassName to target_type"
    )

Two consequences:

  1. The ValueError above, and its guidance to pass module.ClassName, never
    surfaces. Users see an AttributeError instead.
  2. The enclosing try only catches ValueError, so callers passing
    break_on_fail=False receive an exception rather than False.

This switches the read to a defaulted lookup so the existing error path works
as written. No behaviour changes for modules that do define DEFAULT_CLASS.

Reproduction

>>> _plugins.load_plugin("detectors.always", break_on_fail=False)
AttributeError: module 'garak.detectors.always' has no attribute 'DEFAULT_CLASS'

Also reachable from the CLI, e.g. --target_type base.

Testing

Adds test_load_plugin_module_without_default_class to
tests/plugins/test_plugin_load.py, covering both the break_on_fail=False
return value and the ValueError message. The test fails on main and passes
with this change. Full tests/plugins/ suite passes.

@jmartin-tech jmartin-tech self-assigned this Aug 4, 2026
@jmartin-tech

Copy link
Copy Markdown
Collaborator

Test failures here are due to timing of the PR being opened, an upstream fix #2017 existing in main has addressed limiting the dependency that is the root cause of test failures.

Tests can be re-triggered after a rebase or manually validated by a maintainer during review and testing.

load_plugin read generator_mod.DEFAULT_CLASS directly, so a module without
that attribute raised AttributeError before the else branch could run. That
made the 'no default class; pass module.ClassName to target_type' ValueError
unreachable, and callers passing break_on_fail=False got an exception instead
of False. Use a defaulted lookup so the intended error path is reachable.

Signed-off-by: manunicholasjacob <manunicholasjacob@gmail.com>
@manunicholasjacob
manunicholasjacob force-pushed the fix/plugins-default-class branch from 11fe932 to 1a39922 Compare August 5, 2026 17:03
@manunicholasjacob

Copy link
Copy Markdown
Contributor Author

Rebased onto current main, so this now includes #2017. Full matrix is green — 16/16 checks, Linux/macOS/Windows across 3.10/3.12/3.13 — so no manual validation should be needed here.

#2012 is in the same state after the same rebase, if it helps to look at them together.

@jmartin-tech

Copy link
Copy Markdown
Collaborator

Tests were triggered by the team after the rebase push an hour ago, please keep in mind review and PR processing are async and the team will provide feedback as time allows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants