abhigyanpatwari/GitNexus · error
Local embeddings are unavailable after the sidecar aborted
Error message
Local embeddings are unavailable after the sidecar aborted
What it means
This error is thrown by the internal spawnAndInit step of the embedding sidecar client. The sidecar child process previously died in a way indicating a native abort (SIGSEGV/SIGABRT/SIGBUS/SIGILL) or had already exhausted the single recreate attempt (MAX_RECREATES = 1), so the client latches `localUnavailable` and permanently refuses to spawn a new sidecar for this process lifetime. It prevents repeated crashes from an ONNX runtime or native binary that is fundamentally broken in this environment.
Solutions
- Restart the GitNexus process — the `localUnavailable` latch is in-memory only, so a fresh process clears it (after fixing the underlying crash cause).
- Check sidecar stderr in debug logs for the native crash signature; reinstall or update onnxruntime-node / the model runtime so the native binary matches the platform.
- Use a remote embedding provider instead of local embeddings (e.g. configure GITNEXUS_EMBEDDING_URL or an API-based provider) to bypass the sidecar entirely.
- If the crash came from the device choice, retry with a different device (e.g. force CPU instead of GPU) once the process has been restarted.
- Free memory or raise container limits if the abort correlates with model loading OOM.
Example fix
// before: retrying embed calls in a process where the sidecar already aborted
const vectors = await sidecarEmbedBatch(texts); // throws forever
// after: check device availability first and fall back to a remote provider
if (getSidecarDevice() === null) {
const vectors = await remoteEmbedBatch(texts);
} else {
const vectors = await sidecarEmbedBatch(texts);
} Defensive patterns
Strategy: fallback
Validate before calling
// check local runtime availability before requesting local embeddings
import { getLocalEmbeddingRuntimeBlocker } from './runtime-support.js';
const blocker = getLocalEmbeddingRuntimeBlocker();
if (blocker) useRemoteEmbeddings(); Type guard
// narrow to a sidecar-capable state const canEmbedLocally = (): boolean => getSidecarDevice() !== null;
Try / catch
try {
await sidecarInit();
} catch (err) {
if (String(err.message).includes('sidecar aborted')) {
logger.error('Local embeddings permanently unavailable; switching to remote provider');
enableRemoteEmbeddings();
} else {
throw err;
}
} Prevention
- Pin onnxruntime-node versions and test sidecar startup in CI containers
- Avoid forcing a GPU device unless the target host has working CUDA libs
- Monitor sidecar stderr logs for native crash signatures before they latch the flag
When it happens
Trigger: Calling ensureEmbeddingSidecar (directly or via sidecarEmbedBatch) after a prior sidecar died with a native abort signal, or after the sidecar died once, was recreated once, and died again — markUnavailableIfBudgetSpent() sets localUnavailable and line 309 throws on the next spawn attempt.
Common situations: Broken or mismatched onnxruntime-node native binaries; CPU without required instruction sets (e.g. AVX) for the model runtime; sidecar killed by the OS (OOM/segfault) during model download or inference; GPU/CUDA library conflicts when forceDevice was requested.
Related errors
- assessment.message (local embedding runtime…
- response.message (sidecar embed error)
- response.message (sidecar init error)
- runtimeBlocker (local embedding runtime blocker message)
- analyze --watch does not support
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/56b5683517e890bd.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/embeddings/embedding-sidecar-client.ts:309
onProgress?: (progress: ModelProgress) => void;
embeddingConfig?: Partial<EmbeddingConfig>;
forceDevice?: EmbeddingSidecarDevice;
signal?: AbortSignal;
};
const markUnavailableIfBudgetSpent = (): void => {
if (deathSeen && recreatesUsed >= MAX_RECREATES) {
localUnavailable = true;
}
};
const spawnAndInit = async (options?: EnsureSidecarOptions): Promise<void> => {
const runtimeBlocker = getLocalEmbeddingRuntimeBlocker();
if (runtimeBlocker) {
throw new Error(runtimeBlocker);
}
markUnavailableIfBudgetSpent();
if (localUnavailable) throw localUnavailableError();
if (deathSeen) {
recreatesUsed += 1;
deathSeen = false;
}
const persisted = {
embeddingConfig: options?.embeddingConfig ?? lastInitOptions?.embeddingConfig,
forceDevice: options?.forceDevice ?? lastInitOptions?.forceDevice,
};
child = spawnSidecar();
attachChild(child);
progressSink = options?.onProgress;
try {
const response = await request(
{
type: 'init',View on GitHub (pinned to ac9a4e9abd)