refinedev/refine · error · Error

Not implemented custom on data provider.

Error message

Not implemented custom on data provider.

What it means

Thrown by `useCustom` in @refinedev/core when it cannot execute the custom request: the selected data provider doesn't implement the `custom` method (or the query path in the hook fell through to the final `throw Error("Not implemented custom on data provider.")`). useCustom is only usable with providers that implement the optional `custom` capability (e.g. simple-rest, strapi).

Source

Thrown at packages/core/src/hooks/data/useCustom.ts:238

          description: queryResponse.error.message,
          type: "error",
        });
      }
    }, [queryResponse.isError, queryResponse.error?.message]);
    const { elapsedTime } = useLoadingOvertime({
      ...overtimeOptions,
      isLoading: queryResponse.isFetching,
    });

    return {
      query: queryResponse,
      result: {
        data: queryResponse.data?.data || EMPTY_OBJECT,
      },
      overtime: { elapsedTime },
    };
  }
  throw Error("Not implemented custom on data provider.");
};

View on GitHub (pinned to 779d52a20e)

Solutions

  1. Switch to a data provider that implements `custom` (simple-rest/strapi) via `dataProviderName`
  2. Replace useCustom with direct fetch/SDK calls wrapped in react-query's useQuery
  3. Verify the provider you pass exists and supports custom before rendering the component

Example fix

// before
const { data } = useCustom({ url: '/reports/summary', method: 'get' });
// after
const { data } = useQuery({
  queryKey: ['reports', 'summary'],
  queryFn: () => fetch(`${API_URL}/reports/summary`).then((r) => r.json()),
});
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof dataProvider.custom !== 'function') {
  throw new Error('This page requires a provider implementing `custom`');
}

Type guard

const supportsCustom = (dp: unknown): dp is { custom: (o: any) => Promise<any> } =>
  typeof (dp as any)?.custom === 'function';

Try / catch

try {
  const { data } = useCustom(config);
} catch (e) {
  if (/Not implemented custom/.test((e as Error).message)) useDirectFetch(config);
  else throw e;
}

Prevention

When it happens

Trigger: Calling `useCustom({ url, method, ... })` (optionally with a custom dataProviderName) whose provider has no `custom` implementation — the runtime reaches the end of the query flow and throws synchronously/within the hook.

Common situations: Using useCustom with airtable/appwrite/hasura-style providers; passing a wrong `dataProviderName` so the lookup lands on a provider lacking custom; upgrading apps where a provider swap removed custom support.

Related errors


AI-assisted analysis of refinedev/refine@779d52a20e (2026-08-27). Data as JSON: /api/errors/a1d3587456bd4fe9. Report an issue: GitHub.