diff --git a/.changeset/gentle-buses-exist.md b/.changeset/gentle-buses-exist.md
new file mode 100644
index 0000000000..a32f0bf8f0
--- /dev/null
+++ b/.changeset/gentle-buses-exist.md
@@ -0,0 +1,6 @@
+---
+'@backstage/core-api': patch
+'@backstage/core': patch
+---
+
+More informative error message for missing ApiContext.
diff --git a/packages/core-api/src/apis/system/ApiProvider.test.tsx b/packages/core-api/src/apis/system/ApiProvider.test.tsx
index ac64aca3a7..71269697c2 100644
--- a/packages/core-api/src/apis/system/ApiProvider.test.tsx
+++ b/packages/core-api/src/apis/system/ApiProvider.test.tsx
@@ -108,11 +108,11 @@ describe('ApiProvider', () => {
withLogCollector(['error'], () => {
expect(() => {
render();
- }).toThrow('No ApiProvider available in react context');
+ }).toThrow(/^No ApiProvider available in react context. /);
}).error,
).toEqual([
expect.stringMatching(
- /^Error: Uncaught \[Error: No ApiProvider available in react context\]/,
+ /^Error: Uncaught \[Error: No ApiProvider available in react context. /,
),
expect.stringMatching(
/^The above error occurred in the component/,
@@ -123,11 +123,11 @@ describe('ApiProvider', () => {
withLogCollector(['error'], () => {
expect(() => {
render();
- }).toThrow('No ApiProvider available in react context');
+ }).toThrow(/^No ApiProvider available in react context. /);
}).error,
).toEqual([
expect.stringMatching(
- /^Error: Uncaught \[Error: No ApiProvider available in react context\]/,
+ /^Error: Uncaught \[Error: No ApiProvider available in react context. /,
),
expect.stringMatching(
/^The above error occurred in the component/,
diff --git a/packages/core-api/src/apis/system/ApiProvider.tsx b/packages/core-api/src/apis/system/ApiProvider.tsx
index 91d35e5ee7..d41730cb59 100644
--- a/packages/core-api/src/apis/system/ApiProvider.tsx
+++ b/packages/core-api/src/apis/system/ApiProvider.tsx
@@ -24,6 +24,12 @@ import PropTypes from 'prop-types';
import { ApiRef, ApiHolder, TypesToApiRefs } from './types';
import { ApiAggregator } from './ApiAggregator';
+const missingHolderMessage =
+ 'No ApiProvider available in react context. ' +
+ 'A common cause of this error is that multiple versions of @backstage/core-api are installed. ' +
+ `You can check if that is the case using 'yarn backstage-cli versions:check', and can in many cases ` +
+ `fix the issue either with the --fix flag or using 'yarn backstage-cli versions:bump'`;
+
type ApiProviderProps = {
apis: ApiHolder;
children: ReactNode;
@@ -50,7 +56,7 @@ export function useApiHolder(): ApiHolder {
const apiHolder = useContext(Context);
if (!apiHolder) {
- throw new Error('No ApiProvider available in react context');
+ throw new Error(missingHolderMessage);
}
return apiHolder;
@@ -74,7 +80,7 @@ export function withApis(apis: TypesToApiRefs) {
const apiHolder = useContext(Context);
if (!apiHolder) {
- throw new Error('No ApiProvider available in react context');
+ throw new Error(missingHolderMessage);
}
const impls = {} as T;