sundowndev/phoneinfoga · error

given plugin %s is not valid: %v

Error message

given plugin %s is not valid: %v

What it means

After confirming the path exists, OpenPlugin calls Go's plugin.Open to load the shared object. If the file exists but is not a valid loadable plugin, the underlying plugin.Open error is wrapped as 'given plugin %s is not valid: %v'. This usually means build/incompatibility issues rather than a missing file.

Source

Thrown at lib/remote/scanner.go:38

type Plugin interface {
	Lookup(string) (plugin.Symbol, error)
}

type Scanner interface {
	Name() string
	Description() string
	DryRun(number.Number, ScannerOptions) error
	Run(number.Number, ScannerOptions) (interface{}, error)
}

func OpenPlugin(path string) error {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return fmt.Errorf("given path %s does not exist", path)
	}

	_, err := plugin.Open(path)
	if err != nil {
		return fmt.Errorf("given plugin %s is not valid: %v", path, err)
	}

	return nil
}

View on GitHub (pinned to 55807b05b7)

Solutions

  1. Read the wrapped %v detail in the message — it states the exact plugin.Open reason
  2. Rebuild plugin and host with the exact same Go version and flags: 'go build -buildmode=plugin -o scanner.so ./plugin'
  3. Ensure all shared dependencies are at identical versions in both the host and plugin go.mod (mismatched deps cause 'symbol ... undefined' or 'different versions' errors)
  4. Confirm the target OS/arch supports Go plugins (Linux; not Windows/macOS reliably) and the file is actually a .so plugin, not a binary

Example fix

// before
go build -o scanner.so ./scanner        // wrong: not a plugin
// after
go build -buildmode=plugin -o scanner.so ./scanner   # same Go version as host
Defensive patterns

Strategy: try-catch

Validate before calling

info, err := os.Stat(path)
if err != nil || info.IsDir() {
    return fmt.Errorf("not a plugin file: %s", path)
}
if filepath.Ext(path) != ".so" {
    return fmt.Errorf("expected .so plugin, got %s", path)
}

Type guard

func looksLikePlugin(path string) bool {
    info, err := os.Stat(path)
    return err == nil && !info.IsDir() && filepath.Ext(path) == ".so"
}

Try / catch

if err := remote.OpenPlugin(path); err != nil {
    if strings.Contains(err.Error(), "is not valid") {
        return fmt.Errorf("plugin %s failed to load; rebuild with same Go version and -buildmode=plugin: %v", path, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling OpenPlugin(path) on a file that exists but fails plugin.Open: file is not a Go plugin (regular binary, ELF without plugin mode), built with a different Go toolchain version, built without -buildmode=plugin, or compiled with mismatched package versions/flags versus the host binary.

Common situations: Plugin and host built with different Go versions (plugin.Open requires identical toolchain); plugin compiled as a normal executable; plugin references dependency versions that don't match the host's go.mod; trying to open a .dylib/.dll on an unsupported OS (Linux-only); stripped or rebuilt .so after host recompile.

Related errors


AI-assisted analysis of sundowndev/phoneinfoga@55807b05b7 (2026-09-03). Data as JSON: /api/errors/1e23c8ba75a1e9bb. Report an issue: GitHub.