2026-08-03

The same function returns 0.0 or 1.0 depending on what you pip installed

Here is a distance function with four fallback paths, picked at runtime by whichever optional dependency happens to be importable. It is in LangChain, at langchain_classic/evaluation/embedding_distance/base.py:193, and I found it about eight minutes after opening a repository I had never read.

Feed all four paths a zero-magnitude embedding — an empty string that embedded to zeros, a padding row, a degenerate vector — and ask what distance comes back.

pathselected whenreturnswhich means
1langchain_core importable (the default)1.0maximally distant
2scipy fallbacknanundefined
3numpy fallback0.0identical. a perfect match
4pure-python fallback0.0identical. a perfect match

The two most likely paths return opposite ends of the metric for the same input. Not a rounding difference. These are as far apart as two things can be versus these are the same thing, decided by whether simsimd or scipy is in the environment.

Where each one says it

Paths 3 and 4 are explicit, and honestly they are the ones being careful:

if norm_a == 0 or norm_b == 0:
    return 0.0                      # :222 (numpy) and :236 (pure python)

That is a deliberate guard against dividing by zero. It is also, in a distance metric, the statement "these two vectors are identical."

Path 1 arrives at the opposite answer by a different road. It calls _cosine_similarity, which handles the same degenerate case in langchain_core/vectorstores/utils.py:104:

with np.errstate(divide="ignore", invalid="ignore"):
    similarity = np.dot(x, y.T) / np.outer(x_norm, y_norm)
...
similarity[np.isnan(similarity) | np.isinf(similarity)] = 0.0

Also careful, also reasonable — substitute 0.0 for the nan. But this is similarity, and the caller then computes 1.0 - similarity. Zero similarity becomes distance 1.0.

So both authors made the same defensive choice — replace the undefined value with zero — and because one was working in similarity space and the other in distance space, the identical instinct produced inverted results.

Why no tool finds this

Every duplicate-detection tool in existence asks a version of is this the same code written twice, so we can consolidate it. Type 1 and 2 clones — copy-paste, renamed variables — have been solved for decades. Type 3 needs AST analysis and ships today. Type 4, semantically equivalent but syntactically different, is openly still a research problem.

None of that applies here. These four paths are not clones and were never meant to be. They are deliberately different implementations, written at different times, each internally coherent, sharing no code. A clone detector would never pair them, because pairing them is not what it is for.

The bug is not in any of the four implementations. It is in the disagreement between them, and the disagreement does not live in a file.

That is why reading harder does not find it either. Each function, read on its own, is correct and well-guarded. You have to be holding two of them at once, and asking a question neither one asks about itself.

What I verified, and what I only read

This is the part that decides whether any of the above is worth your time:

How to check yours

Find a function in your codebase with more than one implementation selected at runtime — an optional-dependency fallback, a feature flag, a "fast path" and a "safe path". Write down the three or four degenerate inputs it could receive: empty, zero, null, error. Then evaluate every path against every input and put it in a table.

You are not looking for a wrong answer. Every path will look defensible on its own. You are looking for two cells in the same column that disagree — and specifically for the case where both authors did the careful thing and the careful thing meant opposite in their two coordinate systems.


This is what I do for money — a day, together, on your codebase, hunting exactly this: writes that report success without landing, checks that cannot fail, and two implementations that quietly disagree. What that looks like. Or send me one repository and I will run the pass over it and mail you what it finds, free, once. It found nothing is a common result and I will tell you that plainly.

This is one of fourteen. The survey collects every case I have read where a failed check and a passing check produce the same result — named, quoted, with line numbers, including the ones that turned out to be my own mistake.