ramensoftware/windhawk · error · CoreDllError

INTERNAL

INTERNAL

Error message

unknown windhawk-core error

What it means

The VS Code extension's DLL backend invokes windhawk-core over a JSON command channel. When the core replies with an error envelope that has no usable code/message, toCoreDllError falls back to a generic INTERNAL error with message "unknown windhawk-core error". It signals the core rejected or failed the command without providing details.

Solutions

  1. Check that the windhawk-core binary version matches the extension (reinstall/repair Windhawk)
  2. Capture the core's logs/stderr around the failing invoke to see the real cause
  3. Retry the command; transient core-side failures (e.g. service not ready) may resolve
  4. Report the missing error envelope to the Windhawk maintainers if it reproduces consistently

Example fix

// before: treating the thrown error as meaningful
if (err.message === 'unknown windhawk-core error') { ... }
// after: retry with backoff and surface core logs
try { await backend.getMods(); } catch (e) {
  if (e.code === 'INTERNAL') { logCoreDiagnostics(); await retry(getMods); }
}
Defensive patterns

Strategy: retry

Type guard

function isCoreEnvelope(r: unknown): r is { ok: true; result: unknown } | { ok: false; error?: { code?: string; message?: string } } {
  return typeof r === 'object' && r !== null && 'ok' in r;
}

Try / catch

try {
  const result = await backend.someCommand(params);
} catch (e) {
  if (e.code === 'INTERNAL' && /unknown windhawk-core error/.test(e.message)) {
    logCoreDiagnostics();
    await retryWithBackoff(() => backend.someCommand(params), 3);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling any method on the DLL backend created by createDllBackend when the windhawk-core process returns {ok:false} with an error object lacking code/message, or the response cannot be mapped to a concrete error.

Common situations: windhawk-core crashed or returned a malformed error envelope; version mismatch between the extension and the core binary; an unimplemented command reached the core.

Related errors


AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/ee13d04f6cc08cf8. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-vscode/src/coreClient/dllBackend.ts:307

		(opId, eventJson) => {
			// Deliver the event to its operation's handler (the dispatcher
			// deferred until the first async command landed).
			// An unknown id is a harmless no-op (a terminated operation).
			opHandlers.get(opId)?.(JSON.parse(eventJson) as OperationEvent);
		},
	);
	// The session lives for the process: the WindhawkCore contract has no
	// dispose, and the bridge unrefs its callbacks (a leaked session cannot
	// keep the process alive) and tears the session down on GC/exit.

	async function invoke<T>(command: string, params: unknown): Promise<T> {
		const response = JSON.parse(await session.invoke(JSON.stringify({ command, params }))) as
			| { ok: true; result: T }
			| { ok: false; error?: { code?: string; message?: string; details?: unknown } };
		if (response.ok) {
			return response.result;
		}
		throw toCoreDllError(response.error);
	}

	// Start an async command and register its event handler. invokeAsync
	// returns the operation id (or throws the start-failure envelope); the
	// handler is keyed on that id. Returns the id so the caller can cancel.
	function startAsync(
		command: string,
		params: unknown,
		handler: (event: OperationEvent) => void,
	): number {
		const opId = session.invokeAsync(JSON.stringify({ command, params }));
		opHandlers.set(opId, handler);
		return opId;
	}

	// An async command that the contract exposes as a plain Promise (the
	// repository fetches, which emit no progress): resolve on completed,
	// reject on failed, and deregister on either.

View on GitHub (pinned to 61d99ed8e1)