{"record":{"id":"5acabbf301d42ee1","repo":"abhigyanpatwari/GitNexus","slug":"no-suitable-device-found","errorCode":null,"errorMessage":"No suitable device found","messagePattern":"No suitable device found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/mcp/core/embedder.ts","lineNumber":160,"sourceCode":"          // Network errors and circuit-open errors are not device-specific —\n          // they will fail the same way on every device. Rethrow immediately\n          // with actionable HF_ENDPOINT guidance rather than silently falling\n          // back to the next device.\n          const errMsg = deviceError instanceof Error ? deviceError.message : String(deviceError);\n          if (isHfDownloadFailure(errMsg)) {\n            const endpointHint = process.env.HF_ENDPOINT\n              ? `The configured endpoint (${process.env.HF_ENDPOINT}) may be unreachable.`\n              : `huggingface.co may be unreachable from your network.\\n` +\n                `  Set HF_ENDPOINT to a mirror and retry:\\n` +\n                `    HF_ENDPOINT=https://hf-mirror.com npx gitnexus analyze --embeddings\\n` +\n                `    (Windows: set HF_ENDPOINT=https://hf-mirror.com && npx gitnexus analyze --embeddings)`;\n            throw new Error(`Failed to download embedding model: ${errMsg}\\n  ${endpointHint}`);\n          }\n          if (device === 'cpu') throw new Error('Failed to load embedding model');\n        }\n      }\n\n      throw new Error('No suitable device found');\n    } catch (error) {\n      isInitializing = false;\n      initPromise = null;\n      embedderInstance = null;\n      throw error;\n    } finally {\n      isInitializing = false;\n    }\n  })();\n\n  return initPromise;\n};\n\n/**\n * Check if embedder is ready\n */\nexport const isEmbedderReady = (): boolean => isHttpMode() || embedderInstance !== null;\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/mcp/core/embedder.ts#L142-L178","documentation":"Terminal failure of initEmbedder's device-probing loop: every candidate device failed for reasons that did not short-circuit earlier (download failures and the cpu-specific message throw their own errors), so no inference device could run the embedding model. The embedder instance and init promise are reset, so a later call retries the whole probe.","triggerScenarios":"GPU device candidates fail (driver/runtime mismatch, no WebGL/WASM support in the Node build) AND the cpu attempt fails for a non-network reason such as memory exhaustion or a broken native runtime — the loop exhausts all devices without a classifiable error.","commonSituations":"Containers with strict memory limits where model load OOMs on every device; minimal Node runtimes missing WASM support; hosts with mismatched GPU drivers where both accelerated and fallback paths are broken; rarely, deeply corrupted installs.","solutions":["Check for resource exhaustion first: free memory, watch dmesg/task manager for OOM kills, and retry on a less constrained host or container.","Pin a device explicitly with GITNEXUS_EMBEDDING_DEVICE=cpu to skip broken accelerated paths.","Reinstall the embedding stack via `gitnexus embeddings install` to repair a broken onnxruntime/transformers pairing.","Switch to HTTP embeddings with GITNEXUS_EMBEDDING_URL + GITNEXUS_EMBEDDING_MODEL so no local device is needed.","If all routes fail, capture the per-device errors from the logs and file a GitNexus issue."],"exampleFix":"# before: every device candidate fails\n$ gitnexus analyze --embeddings\n# → No suitable device found\n\n# after: pin cpu, repair stack, or move to HTTP embeddings\n$ GITNEXUS_EMBEDDING_DEVICE=cpu gitnexus embeddings install\n$ GITNEXUS_EMBEDDING_DEVICE=cpu gitnexus analyze --embeddings\n# or: export GITNEXUS_EMBEDDING_URL=... GITNEXUS_EMBEDDING_MODEL=... and retry","handlingStrategy":"fallback","validationCode":"// Pre-flight: memory headroom and pinned device before embedding runs\nimport os from 'node:os';\n\nfunction embeddingPreconditionsOk(): boolean {\n  const freeMb = os.freemem() / 1024 / 1024;\n  return freeMb > 1024; // model load needs real headroom, not the bare minimum\n}\nprocess.env.GITNEXUS_EMBEDDING_DEVICE ??= 'cpu'; // skip broken accelerated paths by default","typeGuard":null,"tryCatchPattern":"try {\n  await initEmbedder();\n} catch (err) {\n  if (err instanceof Error && err.message === 'No suitable device found') {\n    // all devices failed: degrade gracefully, index without semantic search\n    logger.warn('embeddings unavailable — continuing without them');\n    return runAnalyze({ embeddings: false });\n  }\n  throw err;\n}","preventionTips":["Reserve adequate memory (container limits, no parallel heavy jobs) during embedding runs.","Set GITNEXUS_EMBEDDING_DEVICE=cpu explicitly on hosts with flaky GPU runtimes.","Keep the embedding stack repaired via `gitnexus embeddings install` after runtime upgrades.","Design pipelines so embeddings are an optional enhancement, never a hard dependency."],"tags":["embeddings","device-selection","onnxruntime","wasm","resource-exhaustion"],"backgroundTag":"no-available-inference-device","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}