gitbutlerapp/gitbutler · warning

unable to log error to file

Error message

unable to log error to file

What it means

tauriLogErrorToFile wraps the Tauri log plugin's logErrorToFile IPC command so the UI can persist error text. The try/catch warns when the write fails — plugin not registered, log directory unwritable or full, or IPC torn down — and deliberately swallows the failure so diagnostics never crash the app. The cost is that the original error text is not persisted anywhere durable.

Source

Thrown at apps/desktop/src/lib/backend/tauri.ts:195

	constructor(private store: Store) {}

	async set(key: string, value: unknown): Promise<void> {
		return await this.store.set(key, value);
	}

	async get<T>(key: string, defaultValue: undefined): Promise<T | undefined>;
	async get<T>(key: string, defaultValue: T): Promise<T>;
	async get<T>(key: string, defaultValue?: T): Promise<T | undefined> {
		const value = await this.store.get<T>(key);
		return value !== undefined ? value : defaultValue;
	}
}

export async function tauriLogErrorToFile(error: string) {
	try {
		await logErrorToFile(error);
	} catch (e: unknown) {
		console.warn("unable to log error to file", e);
	}
}

export function tauriPathSeparator(): string {
	const platformName = platform();
	return platformName === "windows" ? "\\" : "/";
}

async function tauriGetAppInfo(): Promise<AppInfo> {
	const [appName, appVersion] = await Promise.all([getName(), getVersion()]);
	return { name: appName, version: appVersion };
}

async function tauriInvoke<T>(command: string, params: Record<string, unknown> = {}): Promise<T> {
	// This commented out code can be used to delay/reject an api call
	// return new Promise<T>((resolve, reject) => {
	// 	if (command.startsWith('apply')) {
	// 		setTimeout(() => {

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Confirm tauri-plugin-log is registered on the Rust side and the app-data directory is writable
  2. Free disk space or fix directory ownership so the log file can be written
  3. Mirror the original error to console.error in the catch so it is not lost when the file write fails
  4. Queue log writes and flush at startup instead of writing during teardown

Example fix

// before
export async function tauriLogErrorToFile(error: string) {
	try {
		await logErrorToFile(error);
	} catch (e: unknown) {
		console.warn("unable to log error to file", e);
	}
}

// after
export async function tauriLogErrorToFile(error: string) {
	try {
		await logErrorToFile(error);
	} catch (e: unknown) {
		console.warn("unable to log error to file", e);
		console.error("original error (file logging unavailable):", error);
	}
}
Defensive patterns

Strategy: fallback

Validate before calling

async function canLogToFile(): Promise<boolean> {
	try {
		await logErrorToFile("");
		return true;
	} catch {
		return false;
	}
}

Type guard

function isPluginCommandMissing(e: unknown): boolean {
	return e instanceof Error && /command .* not found|plugin/i.test(e.message);
}

Try / catch

try {
	await logErrorToFile(error);
} catch (e) {
	console.warn("unable to log error to file", e);
	console.error("original error:", error); // never lose the payload
}

Prevention

When it happens

Trigger: Awaiting tauriLogErrorToFile(error) when the tauri-plugin-log command is not registered in the running build, the app-data log directory is read-only or the disk is full, or the call races window/app teardown so the IPC invoke rejects.

Common situations: A dev build started without the log plugin; permissions changed on the app-data directory; disk-full machines; logging triggered during webview shutdown or reload.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/17ee4899c4cd1ca4. Report an issue: GitHub.