different-ai/openwork · error · Error

GitHub install start response was incomplete.

Error message

GitHub install start response was incomplete.

What it means

useStartGithubInstall's mutation starts a GitHub App installation: the server responds with an item containing redirectUrl and state. If either is missing/empty after isRecord/asString narrowing, this error is thrown inside the mutation, and a second identical error is thrown when the mutation result comes back null.

Solutions

  1. Verify the GitHub App is fully configured on the Den server (app slug, client ID, secret) so a redirect URL can be generated.
  2. Inspect the raw start-install response to see whether item/redirectUrl/state are present.
  3. Re-authenticate — some servers omit state when the session cannot mint a CSRF token.
  4. Align frontend and server versions so the response matches { item: { redirectUrl, state } }.

Example fix

// before
const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
const redirectUrl = item ? asString(item.redirectUrl) : null;
// after
const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
const redirectUrl = item ? asString(item.redirectUrl) : null;
if (!redirectUrl && isRecord(payload)) console.error("install start payload keys:", Object.keys(payload));
Defensive patterns

Strategy: validation

Validate before calling

// before starting install, verify the app is configured:
const cfg = await requestJson("/v1/connectors/github/config", { method: "GET" }, 10000);
const ready = isRecord(cfg.payload) && typeof cfg.payload.appSlug === "string" && cfg.payload.appSlug.length > 0;
if (!ready) throw new Error("GitHub App not configured on server.");

Type guard

function hasInstallStart(p: unknown): p is { item: { redirectUrl: string; state: string } } {
  if (typeof p !== "object" || p === null) return false;
  const item = (p as { item?: unknown }).item;
  return (
    typeof item === "object" && item !== null &&
    typeof (item as { redirectUrl?: unknown }).redirectUrl === "string" &&
    typeof (item as { state?: unknown }).state === "string"
  );
}

Try / catch

try {
  await startGithubInstall();
} catch (e) {
  setError(e instanceof Error ? e.message : "Could not start GitHub install.");
}

Prevention

When it happens

Trigger: POST to start install returns 200 but item is absent, item.redirectUrl is null/empty, or item.state is null/empty — e.g. the GitHub App is not fully configured so no install URL can be built, or an API shape change moved these fields.

Common situations: GitHub App setup incomplete on the server (missing app slug/client id so redirectUrl can't be generated); CSRF/state secret store misconfigured server-side; frontend/server version mismatch on the item schema.

Related errors


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

Appendix: source

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

      await runReauthableAction("start-github-install", async () => {
      const { response, payload } = await requestJson(
        "/v1/connectors/github/install/start",
        {
          method: "POST",
          body: JSON.stringify({ returnPath: input.returnPath }),
        },
        15000,
      );

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

      const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
      const redirectUrl = item ? asString(item.redirectUrl) : null;
      const state = item ? asString(item.state) : null;
      if (!redirectUrl || !state) {
        throw new Error("GitHub install start response was incomplete.");
      }

        result = { redirectUrl, state };
      });
      if (!result) {
        throw new Error("GitHub install start response was incomplete.");
      }
      return result;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: integrationQueryKeys.all });
    },
  });
}

export function useGithubInstallCompletion(input: { installationId: number | null; state: string | null }) {
  const { runReauthableAction } = useOrgDashboard();

View on GitHub (pinned to 2b7df46e8a)