different-ai/openwork · error · Error

Failed to apply GitHub discovery (${response.status}).

Error message

Failed to apply GitHub discovery (${response.status}).

What it means

Thrown when applying a GitHub discovery result (auto-importing selected repositories as plugins) fails with a non-2xx response. Like all call sites, the error is produced by getRequestError (den-flow.ts:527), which surfaces the server's `error` message or the fallback "Failed to apply GitHub discovery (<status>)."; a 403 {error:'reauth'} payload becomes a ReauthRequiredError.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/integration-data.tsx:810

export function useApplyGithubDiscovery() {
  const queryClient = useQueryClient();
  const { runReauthableAction } = useOrgDashboard();

  return useMutation({
    mutationFn: async (input: { autoImportNewPlugins: boolean; connectorInstanceId: string; selectedKeys: string[] }): Promise<GithubDiscoveryApplyResult> => {
      let result: GithubDiscoveryApplyResult | null = null;
      await runReauthableAction("apply-github-discovery", async () => {
      const { response, payload } = await requestJson(
        `/v1/connector-instances/${encodeURIComponent(input.connectorInstanceId)}/discovery/apply`,
        {
          method: "POST",
          body: JSON.stringify({ autoImportNewPlugins: input.autoImportNewPlugins, selectedKeys: input.selectedKeys }),
        },
        20000,
      );

      if (!response.ok) {
        throw getRequestError(payload, response, `Failed to apply GitHub discovery (${response.status}).`);
      }

      const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
      const createdPlugins = item && Array.isArray(item.createdPlugins)
        ? item.createdPlugins.flatMap((entry) => {
            if (!isRecord(entry)) return [];
            const name = asString(entry.name);
            return name ? [name] : [];
          })
        : [];
      const createdMappingCount = item && Array.isArray(item.createdMappings) ? item.createdMappings.length : 0;
      const materializedConfigObjectCount = item && Array.isArray(item.materializedConfigObjects) ? item.materializedConfigObjects.length : 0;

        result = {
        autoImportNewPlugins: item ? Boolean(item.autoImportNewPlugins) : input.autoImportNewPlugins,
        createdMappingCount,
        materializedConfigObjectCount,
        createdPluginNames: createdPlugins,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the status in the message; for 401/403 force a re-login before retrying.
  2. If 404, refresh the discovery results (re-run discovery) and resubmit with fresh selectedKeys.
  3. If 409, reload existing plugins and deselect already-imported keys.
  4. If 422, validate selectedKeys against the latest discovery payload before submitting.

Example fix

// before
if (!response.ok) {
  throw getRequestError(payload, response, `Failed to apply GitHub discovery (${response.status}).`);
}
// after
if (!response.ok) {
  if (response.status === 404 || response.status === 422) {
    await refetchDiscovery();
    throw new Error("Discovery results are stale — please review and resubmit.");
  }
  throw getRequestError(payload, response, `Failed to apply GitHub discovery (${response.status}).`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before applying discovery
const validKeys = new Set(discoveryResults.map((r) => r.key));
const unknown = selectedKeys.filter((k) => !validKeys.has(k));
if (unknown.length > 0) throw new Error(`Stale selection: ${unknown.join(", ")}`);

Type guard

function isReauthError(e: unknown): e is ReauthRequiredError {
  return e instanceof ReauthRequiredError;
}

Try / catch

try {
  await applyDiscoveryMutation.mutateAsync({ selectedKeys, autoImportNewPlugins });
} catch (error) {
  if (isReauthError(error)) { startReauth(); return; }
  if (/\((404|422)\)/.test(error.message)) { await refetchDiscovery(); }
  showToast(error.message);
}

Prevention

When it happens

Trigger: POST of {autoImportNewPlugins, selectedKeys} with a 20s timeout throws when response.ok is false: 401/403 (expired session or missing permission), 404 (the discovery session or connector instance expired server-side), 409 (selected keys already imported), 422 (selectedKeys no longer valid or malformed), 5xx (server error importing from GitHub).

Common situations: User leaves the discovery screen open, the connector's discovery session expires, then submits; selected repos were deleted or renamed on GitHub; user lacks admin rights on the org; concurrent import by another admin creates duplicate keys.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/313b9920ddd2fe50. Report an issue: GitHub.