{"record":{"id":"b4ae776a6f85b367","repo":"Graphify-Labs/graphify","slug":"key-key-r-already-exists-in-minhashlsh","errorCode":null,"errorMessage":"Key {key!r} already exists in MinHashLSH","messagePattern":"Key (.+?) already exists in MinHashLSH","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"graphify/_minhash.py","lineNumber":94,"sourceCode":"            )\n            err = 0.5 * fp + 0.5 * fn\n            if err < best_err:\n                best_err, best = err, (b, r)\n    _LSH_PARAMS_CACHE[key] = best\n    return best\n\n\nclass MinHashLSH:\n    \"\"\"Band-hashing LSH — same API as datasketch.MinHashLSH for the subset used here.\"\"\"\n\n    def __init__(self, threshold: float = 0.5, num_perm: int = 128) -> None:\n        self.b, self.r = _optimal_lsh_params(threshold, num_perm)\n        self._tables: list[dict[bytes, list[str]]] = [{} for _ in range(self.b)]\n        self._keys: set[str] = set()\n\n    def insert(self, key: str, minhash: MinHash) -> None:\n        if key in self._keys:\n            raise ValueError(f\"Key {key!r} already exists in MinHashLSH\")\n        self._keys.add(key)\n        hv = minhash.hashvalues\n        for i, table in enumerate(self._tables):\n            band = hv[i * self.r : (i + 1) * self.r].tobytes()\n            table.setdefault(band, []).append(key)\n\n    def query(self, minhash: MinHash) -> list[str]:\n        hv = minhash.hashvalues\n        candidates: set[str] = set()\n        for i, table in enumerate(self._tables):\n            band = hv[i * self.r : (i + 1) * self.r].tobytes()\n            candidates.update(table.get(band, []))\n        return list(candidates)\n","sourceCodeStart":76,"sourceCodeEnd":108,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/_minhash.py#L76-L108","documentation":"Fail-fast guard in the Windows flavor of the graphify skill template (tools/skillgen/expected/graphify__skill-windows.md:441), identical in logic to the bash variant: after build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED), a graph with zero nodes aborts via SystemExit(1) before any output file is written. It protects the existing graph.json / GRAPH_REPORT.md / analysis sidecar from being clobbered by an empty extraction (#1392).","triggerScenarios":"Executing the PowerShell here-string pipeline (& (Get-Content graphify-out\\.graphify_python) -) when .graphify_extract.json yields zero nodes: all files skipped during detection, a binary-only corpus, or an upstream extraction failure that still emitted a valid-but-empty JSON file.","commonSituations":"Running the skill on Windows against a directory of binaries or generated artifacts; a path-quoting mistake in PowerShell so the extractor scanned nothing; extraction stage failed (e.g. token/quota error) but wrote an empty result; line-ending or encoding corruption making every file unparseable to the detector.","solutions":["Inspect graphify-out/.graphify_extract.json and confirm the nodes array is empty; if so, re-run extraction against a tree with real text sources.","Verify the PowerShell invocation passed the correct INPUT_PATH (quoting/relative path issues on Windows are the usual culprit for 'scanned nothing').","Delete the .graphify_extract.json / .graphify_detect.json sidecars and re-run the full pipeline so stale empty artifacts are not reused.","Check the detection stage output (.graphify_detect.json) to see which files were skipped and why."],"exampleFix":"# before: extractor ran against a binary-only folder\n/graphify ./dist\n# ERROR: Graph is empty ...\n\n# after: target the source tree, clear stale sidecars\nRemove-Item graphify-out\\.graphify_extract.json, graphify-out\\.graphify_detect.json\n/graphify .\\src","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nextract = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding='utf-8'))\nnodes = extract.get('nodes') or []\nif not nodes:\n    raise SystemExit('extraction produced 0 nodes - check detection skip list before building')\ndetect = json.loads(Path('graphify-out/.graphify_detect.json').read_text(encoding='utf-8'))\nprint('nodes:', len(nodes), '| detection entries:', len(detect) if isinstance(detect, list) else 'n/a')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Precheck the extract sidecar's nodes count before running the PowerShell build pipeline.","Quote INPUT_PATH correctly in PowerShell so the extractor scans the intended tree.","Run from the directory the skill expects; relative sidecar paths silently miss otherwise.","Remove stale .graphify_extract.json/.graphify_detect.json before rebuilding."],"tags":["graphify","windows","powershell","empty-graph","fail-fast"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}