{"record":{"id":"5bcfab29c82472fc","repo":"RyanCodrai/turbovec","slug":"param-must-be-one-of-list-valid-modes-got","errorCode":null,"errorMessage":"{param} must be one of {list(_VALID_MODES)}, got {value!r}","messagePattern":"(.+?) must be one of (.+?), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"turbovec-python/python/turbovec/_similarity.py","lineNumber":36,"sourceCode":"reference stores (LangChain's ``InMemoryVectorStore`` maps the resulting\nNaN cosine to 0.0; Haystack's ``InMemoryDocumentStore`` substitutes a\nnorm of 1, which leaves the zero dot product intact).\n\"\"\"\n\nfrom __future__ import annotations\n\nimport numpy as np\n\nCOSINE = \"cosine\"\nDOT_PRODUCT = \"dot_product\"\n_VALID_MODES = (COSINE, DOT_PRODUCT)\n\n\ndef validate_similarity(value: str, *, param: str = \"similarity\") -> str:\n    \"\"\"Return ``value`` if it names a supported similarity mode, else\n    raise a ``ValueError`` naming the parameter and the valid options.\"\"\"\n    if value not in _VALID_MODES:\n        raise ValueError(\n            f\"{param} must be one of {list(_VALID_MODES)}, got {value!r}\"\n        )\n    return value\n\n\ndef l2_normalize_rows(vectors: np.ndarray) -> np.ndarray:\n    \"\"\"Return a float32 copy of the 2D batch ``vectors`` with every row\n    L2-normalized. Rows with zero norm are kept as-is (see module\n    docstring). Pure computation — safe to run outside store locks.\"\"\"\n    norms = np.linalg.norm(vectors, axis=1, keepdims=True)\n    # Substitute 1.0 for zero norms so zero rows pass through unchanged\n    # instead of dividing by zero.\n    out = vectors / np.where(norms == 0.0, 1.0, norms)\n    return np.ascontiguousarray(out, dtype=np.float32)\n\n\n__all__ = [\n    \"COSINE\",","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/RyanCodrai/turbovec/blob/ccab9f325e6ce2a270a87daf01ae4e443bcf2d49/turbovec-python/python/turbovec/_similarity.py#L18-L54","documentation":"validate_similarity checks that a similarity mode string is one of the supported values in _VALID_MODES before it is used to configure a similarity search. If the value is unknown, a ValueError names the parameter and lists the valid options. This fail-fast validation prevents an invalid mode from silently degrading search results.","triggerScenarios":"Passing an unsupported string for the similarity parameter to validate_similarity (typically via __init__ of a similarity/index object), e.g. similarity='euclidian' (typo) or 'cosine_similarity' instead of a valid mode name.","commonSituations":"Typos in mode names, copying config from another vector library with different mode vocabulary, building the mode string from user input or environment variables without whitelist validation, or a renamed mode after a library upgrade.","solutions":["Use one of the modes listed in the error message (from _VALID_MODES) exactly as spelled.","Check the current library docs/source for the valid mode names — they may have changed between versions.","If the value comes from config/user input, validate it against the supported list before constructing the object."],"exampleFix":"// before\nindex = TurboIndex(similarity=\"cosine_sim\")\n// after\nindex = TurboIndex(similarity=\"cosine\")  # must be in _VALID_MODES","handlingStrategy":"validation","validationCode":"from turbovec._similarity import validate_similarity, _VALID_MODES\nmode = validate_similarity(cfg.get(\"similarity\", \"cosine\"))","typeGuard":null,"tryCatchPattern":"try:\n    mode = validate_similarity(user_value)\nexcept ValueError as e:\n    print(e)  # message lists all valid modes\n    mode = \"cosine\"","preventionTips":["Whitelist-validate mode strings read from config or user input before constructing objects.","Copy mode names directly from the library's public constants, not from other libraries' docs.","Review the changelog when upgrading in case mode names changed."],"tags":["validation","configuration","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"ccab9f325e6ce2a270a87daf01ae4e443bcf2d49","analyzedAt":"2026-09-06T08:39:18.516Z","contentChangedAt":"2026-09-06T08:39:18.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}