cube-js/cube · critical
Cube API client is not provided
Error message
Cube API client is not provided
What it means
useCubeQuery's internal fetch() resolves the API client from options.cubeApi or the CubeContext provider. If neither supplies a CubeApi instance, it throws because there is no client to send the query to.
Source
Thrown at packages/cubejs-client-react/src/hooks/cube-query.ts:91
const [isLoading, setLoading] = useState(!options.skip);
const [resultSet, setResultSet] = useState<ResultSet | null>(null);
const [progress, setProgress] = useState<ProgressResponse | null>(null);
const [error, setError] = useState<Error | null>(null);
const context = useContext(CubeContext);
let subscribeRequest: UnsubscribeObj | null = null;
// `progressResponse` is not part of the public `ProgressResult` API
const progressCallback: ProgressCallback = (progressResult) => setProgress(
(progressResult as unknown as ProgressResultWithResponse).progressResponse
);
async function fetch() {
const { resetResultSetOnChange } = options;
const cubeApi = options.cubeApi || context?.cubeApi;
if (!cubeApi) {
throw new Error('Cube API client is not provided');
}
if (resetResultSetOnChange) {
setResultSet(null);
}
setError(null);
setLoading(true);
try {
const response = await cubeApi.load(query, {
mutexObj: mutexRef.current,
mutexKey: 'query',
progressCallback,
castNumerics: Boolean(typeof options.castNumerics === 'boolean' ? options.castNumerics : context?.options?.castNumerics),
...(options.cache ? { cache: options.cache } : {}),
});
View on GitHub (pinned to 7d981676b3)
Solutions
- Wrap the component tree in <CubeProvider cubeApi={cubeApi('token', { apiUrl })}>.
- Pass the client directly: useCubeQuery(query, { cubeApi }).
- Ensure the hook is used in a child component of CubeProvider, not a sibling/parent.
- Fix ordering issues where a context consumer reads context before the provider sets cubeApi.
Example fix
// before
const { resultSet } = useCubeQuery(query); // no provider, no cubeApi
// after
const [cubeApi] = useState(() => cube('CUBEJS_TOKEN', { apiUrl: 'http://localhost:4000/cubejs-api/v1' }));
const { resultSet } = useCubeQuery(query, { cubeApi }); Defensive patterns
Strategy: validation
Validate before calling
if (!options.cubeApi && !context?.cubeApi) {
throw new Error('useCubeQuery requires a cubeApi via options or CubeProvider');
} Type guard
function isCubeApi(v: unknown): v is { load: Function; sql: Function } {
return !!v && typeof v === 'object' && typeof (v as any).load === 'function';
} Try / catch
try {
const { resultSet } = useCubeQuery(query);
} catch (e) {
if (e.message === 'Cube API client is not provided') {
console.error('Wrap your app in <CubeProvider cubeApi={...}> or pass options.cubeApi');
}
} Prevention
- Wrap the whole component tree in <CubeProvider>.
- Pass cubeApi explicitly in options when outside a provider.
- Keep @cubejs-client/react and @cubejs-client/core versions aligned.
- Write a test that renders the hook without a provider to fail fast in CI.
When it happens
Trigger: Calling useCubeQuery outside a <CubeProvider> without passing { cubeApi } in options; passing cubeApi: undefined; rendering the hook before context is populated.
Common situations: Forgot to wrap the app in <CubeProvider cubeApi={cubeApi(...)}>; using the hook in a component tree that sits above the provider; dynamically rendering a chart component that imports the hook without a client; testing the hook without a wrapper.
Related errors
- A user-defined contextToApiScopes function returns an incons
- A user-defined contextToApiScopes function returns a wrong s
- Unload is not configured. Please define CUBEJS_AWS_S3_OUTPUT
- Export bucket is not configured.
- Auth isn't set
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/031b2d8ab8e6d05a.
Report an issue: GitHub.