trufflesecurity/trufflehog · error

%s is not a valid regex, error received: %v

Error message

%s is not a valid regex, error received: %v

What it means

TruffleHog's JDBC detector exposes WithIgnorePattern as a functional option: it takes a slice of regex strings used to suppress false-positive JDBC connection strings, compiles each one with Go's stdlib regexp package, and panics with this message as soon as regexp.Compile fails. The panic fires when New(...) applies the option, i.e. at scanner construction time, before any scanning happens. The message embeds both the offending pattern and the compiler's reason, so the panic text is the diagnosis.

Source

Thrown at pkg/detectors/jdbc/jdbc.go:39

func New(opts ...func(*Scanner)) *Scanner {
	scanner := &Scanner{
		ignorePatterns: []regexp.Regexp{},
	}
	for _, opt := range opts {
		opt(scanner)
	}

	return scanner
}

func WithIgnorePattern(ignoreStrings []string) func(*Scanner) {
	return func(s *Scanner) {
		var ignorePatterns []regexp.Regexp
		for _, ignoreString := range ignoreStrings {
			ignorePattern, err := regexp.Compile(ignoreString)
			if err != nil {
				panic(fmt.Sprintf("%s is not a valid regex, error received: %v", ignoreString, err))
			}
			ignorePatterns = append(ignorePatterns, *ignorePattern)
		}

		s.ignorePatterns = ignorePatterns
	}
}

// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil)

var (
	// Matches typical JDBC connection strings.
	// The terminal character class additionally excludes () and & to avoid
	// capturing surrounding delimiters (e.g. "(jdbc:…)" or "…&user=x&").
	keyPat = regexp.MustCompile(`(?i)jdbc:[\w]{3,10}:[^\s"'<>,{}[\]]{10,511}[^\s"'<>,{}[\]()&]`)
)

View on GitHub (pinned to bcfcf73aaf)

Solutions

  1. Read the panic string: it names the exact bad pattern and the compiler error (e.g. 'missing closing )'); fix that specific pattern first.
  2. If the pattern was copied from a glob/PCRE tool, convert it: '*.internal.example.com' -> `.*\.internal\.example\.com`, and escape regex metacharacters ( . + ? ( ) [ ] { } | ^ $ ).
  3. Write patterns as Go raw string literals (backticks) so you write one backslash instead of two and avoid escaping mistakes in interpreted strings.
  4. Validate the whole pattern list with regexp.Compile at your config boundary and return a normal error, instead of letting the library panic at startup.
  5. If patterns are fully untrusted and you cannot validate upstream, wrap the New() call in a defer/recover to convert the panic into an error.

Example fix

// before
s := jdbc.New(jdbc.WithIgnorePattern([]string{"jdbc:mysql://*.stage.example.com"})) // panics: '*' has nothing to repeat

// after
s := jdbc.New(jdbc.WithIgnorePattern([]string{`jdbc:mysql://.*\.stage\.example\.com`}))
Defensive patterns

Strategy: validation

Validate before calling

import (
	"fmt"
	"regexp"
)

// Run BEFORE jdbc.New(jdbc.WithIgnorePattern(...)). Uses stdlib regexp,
// the same engine the jdbc detector compiles with.
func compileIgnorePatterns(patterns []string) ([]*regexp.Regexp, error) {
	compiled := make([]*regexp.Regexp, 0, len(patterns))
	for _, p := range patterns {
		re, err := regexp.Compile(p)
		if err != nil {
			return nil, fmt.Errorf("invalid jdbc ignore pattern %q: %w", p, err)
		}
		compiled = append(compiled, re)
	}
	return compiled, nil
}

if _, err := compileIgnorePatterns(cfg.JdbcIgnorePatterns); err != nil {
	return err // fail config validation, never reach jdbc.New()
}

Type guard

// True when the string is safely passable to jdbc.WithIgnorePattern.
func isValidIgnorePattern(pattern string) bool {
	_, err := regexp.Compile(pattern)
		return err == nil
}

Try / catch

// Last-resort conversion of the constructor panic into an error.
func newJdbcScanner(opts ...func(*jdbc.Scanner)) (sc *jdbc.Scanner, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("jdbc scanner construction failed: %v", r)
		}
	}()
	return jdbc.New(opts...), nil
}

Prevention

When it happens

Trigger: Calling jdbc.New(jdbc.WithIgnorePattern([]string{...})) where at least one string is not compilable by Go's RE2-based regexp: unbalanced '(' or '[', a trailing backslash, a repetition operator with nothing to repeat (e.g. '*.example.com' or '+foo'), an invalid named group like '(?P<>', or a reverse character range like '[z-a]'. The panic happens inside the option closure that New() invokes, so the crash occurs on the New() call line, not during FromData().

Common situations: Embedding trufflehog as a library and feeding ignore patterns from CLI flags, env vars, or CI config without pre-validation; copying glob patterns from .gitignore-style configs ('*.internal.example.com') into a regex field; under- or over-escaping in interpreted string literals ("\." vs "\\." vs "\\\\."); hand-editing a pattern list and shipping without running the detector tests (TestJdbc_FromDataWithIgnorePattern exercises this option).

Related errors


AI-assisted analysis of trufflesecurity/trufflehog@bcfcf73aaf (2026-08-15). Data as JSON: /api/errors/3c2a06aa2fc0178a. Report an issue: GitHub.