{"record":{"id":"7365c2675d48901c","repo":"projectdiscovery/katana","slug":"unknown-similarity-mode-q-want-simhash-tfidf-o","errorCode":null,"errorMessage":"unknown similarity mode %q (want simhash, tfidf, or bm25)","messagePattern":"unknown similarity mode %q \\(want simhash, tfidf, or bm25\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/similarity/index.go","lineNumber":71,"sourceCode":"\tmu       sync.Mutex\n\tcorpus   *lexicalCorpus\n\tsigs     []simRep\n\tnextID   uint64\n\tclusters map[string]int // stable clusterID -> accepted count\n\tstats    Stats\n}\n\n// ParseMode validates a mode string.\nfunc ParseMode(s string) (Mode, error) {\n\tswitch Mode(strings.ToLower(strings.TrimSpace(s))) {\n\tcase \"\", ModeSimHash:\n\t\treturn ModeSimHash, nil\n\tcase ModeTFIDF:\n\t\treturn ModeTFIDF, nil\n\tcase ModeBM25:\n\t\treturn ModeBM25, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unknown similarity mode %q (want simhash, tfidf, or bm25)\", s)\n\t}\n}\n\n// New creates an Index. Invalid/zero config fields are filled with defaults.\nfunc New(cfg Config) (*Index, error) {\n\tif cfg.Mode == \"\" {\n\t\tcfg.Mode = DefaultMode\n\t}\n\tmode, err := ParseMode(string(cfg.Mode))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Mode = mode\n\tif cfg.HammingDistance <= 0 {\n\t\tcfg.HammingDistance = DefaultHammingDistance\n\t}\n\tif cfg.ScoreThreshold <= 0 || cfg.ScoreThreshold > 1 {\n\t\tcfg.ScoreThreshold = DefaultScoreThreshold","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/projectdiscovery/katana/blob/e3e742739c3746f085943ce918fb4e2b8daf6fe6/pkg/similarity/index.go#L53-L89","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\ncfg := similarity.Config{Mode: \"SimHash\"}\nidx, err := similarity.New(cfg) // error: unknown similarity mode\n// after\nmode, err := similarity.ParseMode(strings.ToLower(strings.TrimSpace(cfgRaw.Mode)))\nif err != nil {\n    mode = similarity.ModeSimHash\n}\nidx, err := similarity.New(similarity.Config{Mode: mode})","handlingStrategy":"validation","validationCode":"func validMode(s string) bool {\n    switch strings.ToLower(strings.TrimSpace(s)) {\n    case \"simhash\", \"tfidf\", \"bm25\":\n        return true\n    }\n    return false\n}","typeGuard":"func isSimilarityMode(s string) bool {\n    return s == similarity.ModeSimHash || s == similarity.ModeTFIDF || s == similarity.ModeBM25\n}","tryCatchPattern":"idx, err := similarity.New(cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"unknown similarity mode\") {\n        log.Printf(\"bad mode %q, falling back to simhash\", cfg.Mode)\n        cfg.Mode = similarity.ModeSimHash\n        idx, err = similarity.New(cfg)\n    }\n}","preventionTips":["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."],"tags":["config","similarity","invalid-input"],"backgroundTag":"invalid-config-value","analyzedSha":"e3e742739c3746f085943ce918fb4e2b8daf6fe6","analyzedAt":"2026-09-03T14:55:13.248Z","contentChangedAt":"2026-09-03T14:55:13.248Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}