gitbutlerapp/gitbutler · error

No provider found for

Error message

No provider found for ${token.toString()}

What it means

packages/core's inject() retrieves a value from Svelte's context system by an InjectionToken's key and throws when nothing was provided for that token. Every inject(token) call must be matched by a setContext(token, value) in an ancestor component; the throw fires when the token has no provider in the current component tree path.

Solutions

  1. Ensure setContext(token, value) for the token is called in an ancestor component before the consuming component initialises.
  2. Wrap test renderings in a provider component (or a context wrapper helper) that provides all required services.
  3. Make sure inject() is called during component initialisation (top level of the component), not in async callbacks or event handlers.
  4. Verify provide and consume use the exact same token instance (same import path, no duplicate package installs).

Example fix

// before
// Component.ts: outside provider tree
const projects = inject(projectsService); // throws: No provider found

// after
// App root: provide first
setContext(projectsService_token, new ProjectsService());
// Component.ts (child):
const projects = inject(projectsService); // resolves
Defensive patterns

Strategy: try-catch

Try / catch

let projects: ProjectsService;
try {
  projects = inject(projectsService);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("No provider found")) {
    projects = new ProjectsService(); // or fail fast with a clear setup error
  } else throw e;
}

Prevention

When it happens

Trigger: Calling inject(stackService)/inject(uiState)/inject(projectsService) etc. from a component rendered outside the subtree where setContext was called — e.g. a component mounted via a portal, a module-level singleton instantiation outside component initialisation, tests rendering components without the provider wrapper, or a typo/different token instance than the one provided.

Common situations: Unit tests mounting a component without the app's provider hierarchy; Svelte lifecycle violation (calling inject outside component init, so getContext returns undefined); rendering UI outside the root layout where services are provided; duplicate package versions creating two distinct token instances so provide/inject keys don't match.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/2fc8172d0e832334. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/context.ts:55

	setContext(token._key, value);
}

/**
 * Provides many injectables in one call.
 */
export function provideAll(entries: [InjectionToken<any>, any][]) {
	for (const [token, value] of entries) {
		provide(token, value);
	}
}

/**
 * An injector for use with `InjectionToken` rather than `Constructor`.
 */
export function inject<T>(token: InjectionToken<T>): T {
	const value = svelteGetContext<T>(token._key);
	if (value === undefined) {
		throw new Error(`No provider found for ${token.toString()}`);
	}
	return value;
}

/**
 * Injects a value using an injection token with a fallback
 * Returns the default value if the token is not found
 */
export function injectOptional<T>(token: InjectionToken<T>, defaultValue: T): T {
	const value = svelteGetContext<T>(token._key);
	return value !== undefined ? value : defaultValue;
}

View on GitHub (pinned to 58e5313667)