projectdiscovery/katana · error
unknown similarity mode %q (want simhash, tfidf, or bm25)
Error message
unknown similarity mode %q (want simhash, tfidf, or bm25)
What it means
ParseMode validates a similarity mode string and rejects anything other than the three supported modes: simhash, tfidf, and bm25. New() calls ParseMode on Config.Mode, so constructing an Index with a misspelled or unsupported mode string fails immediately with this error.
Source
Thrown at pkg/similarity/index.go:71
mu sync.Mutex
corpus *lexicalCorpus
sigs []simRep
nextID uint64
clusters map[string]int // stable clusterID -> accepted count
stats Stats
}
// ParseMode validates a mode string.
func ParseMode(s string) (Mode, error) {
switch Mode(strings.ToLower(strings.TrimSpace(s))) {
case "", ModeSimHash:
return ModeSimHash, nil
case ModeTFIDF:
return ModeTFIDF, nil
case ModeBM25:
return ModeBM25, nil
default:
return "", fmt.Errorf("unknown similarity mode %q (want simhash, tfidf, or bm25)", s)
}
}
// New creates an Index. Invalid/zero config fields are filled with defaults.
func New(cfg Config) (*Index, error) {
if cfg.Mode == "" {
cfg.Mode = DefaultMode
}
mode, err := ParseMode(string(cfg.Mode))
if err != nil {
return nil, err
}
cfg.Mode = mode
if cfg.HammingDistance <= 0 {
cfg.HammingDistance = DefaultHammingDistance
}
if cfg.ScoreThreshold <= 0 || cfg.ScoreThreshold > 1 {
cfg.ScoreThreshold = DefaultScoreThresholdView on GitHub (pinned to e3e742739c)
Solutions
- Set Config.Mode to one of the exact constants (ModeSimHash, ModeTFIDF, ModeBM25) instead of a raw string literal.
- Normalize user input: strings.ToLower(strings.TrimSpace(mode)) before calling ParseMode/New.
- Check the configured value against the valid list "simhash, tfidf, bm25" and correct the typo in your config file.
- Fall back to a default mode when the configured value fails to parse.
Example fix
// before
cfg := similarity.Config{Mode: "SimHash"}
idx, err := similarity.New(cfg) // error: unknown similarity mode
// after
mode, err := similarity.ParseMode(strings.ToLower(strings.TrimSpace(cfgRaw.Mode)))
if err != nil {
mode = similarity.ModeSimHash
}
idx, err := similarity.New(similarity.Config{Mode: mode}) Defensive patterns
Strategy: validation
Validate before calling
func validMode(s string) bool {
switch strings.ToLower(strings.TrimSpace(s)) {
case "simhash", "tfidf", "bm25":
return true
}
return false
} Type guard
func isSimilarityMode(s string) bool {
return s == similarity.ModeSimHash || s == similarity.ModeTFIDF || s == similarity.ModeBM25
} Try / catch
idx, err := similarity.New(cfg)
if err != nil {
if strings.Contains(err.Error(), "unknown similarity mode") {
log.Printf("bad mode %q, falling back to simhash", cfg.Mode)
cfg.Mode = similarity.ModeSimHash
idx, err = similarity.New(cfg)
}
} Prevention
- Use the exported Mode* constants, never string literals, when building Config.
- Lowercase and trim user-supplied mode values before parsing.
- Validate config at startup with ParseMode so failures are immediate and obvious.
When it happens
Trigger: Passing Config{Mode: "sim-hash"}, "SIMHASH", "cosine", or any string not exactly matching ModeSimHash/ModeTFIDF/ModeBM25 to similarity.New, or the same invalid string to ParseMode directly (also exercised by TestParseMode).
Common situations: Config read from YAML/JSON where the mode value is user-supplied or typo'd; case-sensitivity surprises ("SimHash" vs "simhash"); upgrading the library and referencing a mode that was removed or renamed.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03).
Data as JSON: /api/errors/7365c2675d48901c.
Report an issue: GitHub.