{"record":{"id":"824f5ecb86f7aa14","repo":"Egonex-AI/Understand-Anything","slug":"fingerprints-json-existed-and-was-non-empty-but-lo","errorCode":null,"errorMessage":"fingerprints.json existed and was non-empty but loaded as {} — refusing to overwrite","messagePattern":"fingerprints\\.json existed and was non-empty but loaded as (.+?) — refusing to overwrite","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"understand-anything-plugin/hooks/auto-update-prompt.md","lineNumber":287,"sourceCode":"   //    `filesToReanalyze` may include paths that were deleted in this commit —\n   //    handle both branches inline rather than expecting a separate deleted list.\n   for (const filePath of filesToReanalyze) {\n     const fullPath = path.join(PROJECT_ROOT, filePath);\n     if (!existsSync(fullPath)) {\n       delete all[filePath];\n       continue;\n     }\n     const content = readFileSync(fullPath, 'utf-8');\n     const contentHash = createHash('sha256').update(content).digest('hex');\n     // Extract functions, classes, imports, exports via the same regex as Phase 1.\n     all[filePath] = { contentHash, functions, classes, imports, exports };\n   }\n\n   // 3. GUARD against silent load failure: if fingerprints.json existed and was\n   //    non-empty but `before` came out as 0, refuse to overwrite — something\n   //    went wrong reading the file and writing now would clobber every entry.\n   if (existedAndNonEmpty && before === 0) {\n     throw new Error('fingerprints.json existed and was non-empty but loaded as {} — refusing to overwrite');\n   }\n\n   // 4. SAVE ALL entries back (full dict — not just the patched subset)\n   writeFileSync(fpPath, JSON.stringify(all, null, 2));\n   console.log(`Fingerprints: ${before} → ${Object.keys(all).length}`);\n   ```\n\n   The `existedAndNonEmpty && before === 0` guard catches the silent-load-failure case before it corrupts the store. If the count shrinks from N to a small number that matches the batch size, the LOAD step was skipped — abort the write rather than persist the wrong dict.\n\n4. Clean up intermediate files:\n   ```bash\n   INTERMEDIATE_DIR=\"$UA_DIR/intermediate\"\n   if [ -n \"$PROJECT_ROOT\" ] && [ -d \"$INTERMEDIATE_DIR\" ]; then\n     rm -rf \"$INTERMEDIATE_DIR\"\n   fi\n   ```\n\n5. Report a summary:","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/Egonex-AI/Understand-Anything/blob/32944829e7a63a9fa9c55d811d7f98a9530c6a6a/understand-anything-plugin/hooks/auto-update-prompt.md#L269-L305","documentation":"Thrown by the auto-update hook's fingerprint-update logic when fingerprints.json existed and was non-empty on disk but the in-memory load ('before') came out as zero entries. This is a deliberate guard against a silent load failure: writing the freshly-computed subset would clobber all pre-existing entries. The hook refuses to overwrite rather than destroy the store.","triggerScenarios":"fingerprints.json is non-empty but unreadable as JSON in the load step (corruption, encoding issue, BOM, partial write), yet the readFileSync did not throw — yielding an empty object. The guard then sees existedAndNonEmpty === true and before === 0 and aborts before writeFileSync.","commonSituations":"A previous run was killed mid-write leaving invalid JSON; an editor or merge tool re-saved fingerprints.json with formatting the loader cannot parse; concurrent processes racing on the file; disk/filesystem corruption; a sync tool writing a placeholder empty object.","solutions":["Inspect fingerprints.json for validity (parse it as JSON); repair or restore from version control if corrupt.","If the store is genuinely stale and you want to rebuild it, back it up then delete it so existedAndNonEmpty is false and the guard no longer trips.","Ensure no other process is writing fingerprints.json concurrently with the hook.","Re-run the hook after the file is in a valid state — the full dict will be rewritten, not just a batch subset."],"exampleFix":"# before — guard trips because fingerprints.json is corrupt but non-empty\n# after — repair or reset the store, then re-run\nmv .ua/fingerprints.json .ua/fingerprints.json.bak && rm .ua/fingerprints.json\n# re-run the auto-update hook","handlingStrategy":"validation","validationCode":"const existedAndNonEmpty = existsSync(fpPath) && statSync(fpPath).size > 0;\nlet before = 0;\nif (existedAndNonEmpty) {\n  try { before = Object.keys(JSON.parse(readFileSync(fpPath, 'utf-8'))).length; }\n  catch { before = 0; }\n}\nif (existedAndNonEmpty && before === 0) { /* abort: corrupt store, do not write */ }","typeGuard":"function isFingerprintStore(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Treat the guard as load-bearing: never bypass existedAndNonEmpty && before === 0.","Back up fingerprints.json before re-running the hook when this fires.","Ensure no concurrent process writes fingerprints.json during the hook."],"tags":["hooks","fingerprint","data-integrity","guard"],"backgroundTag":null,"analyzedSha":"32944829e7a63a9fa9c55d811d7f98a9530c6a6a","analyzedAt":"2026-08-12T10:25:44.261Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}