different-ai/openwork · error
GitHub plugin preview response was incomplete.
Error message
GitHub plugin preview response was incomplete.
What it means
parseGithubPluginImportPreview validates the payload returned by the GitHub plugin import preview endpoint. It only accepts a JSON object containing a nested `item` object; anything else (null, array, string, or an object without `item`) triggers this error. The library throws eagerly so callers never work with a partially-shaped preview object.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-screen.tsx:206
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
}
function asString(value: unknown): string | null {
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
}
function parseSkippedReason(value: unknown): GithubPluginImportSkippedReason | null {
if (value === "headers_unsupported" || value === "invalid_config" || value === "invalid_url" || value === "local_unsupported" || value === "missing_url" || value === "unsupported_auth") {
return value;
}
return null;
}
function parseGithubPluginImportPreview(payload: unknown): GithubPluginImportPreview {
const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
if (!item) throw new Error("GitHub plugin preview response was incomplete.");
return {
repositoryFullName: asString(item.repositoryFullName) ?? "",
rootPath: asString(item.rootPath) ?? "",
servers: Array.isArray(item.servers)
? item.servers.flatMap((entry) => {
if (!isRecord(entry)) return [];
const name = asString(entry.name);
const serverKey = asString(entry.serverKey);
if (!name || !serverKey) return [];
return [{
name,
serverKey,
url: asString(entry.url),
supported: entry.supported === true,
skippedReason: parseSkippedReason(entry.skippedReason),
}];
})View on GitHub (pinned to 2b7df46e8a)
Solutions
- Log the raw response body (network tab or `await response.text()`) and confirm whether `item` is present at the top level
- Verify the frontend and den-api server versions match — redeploy or pull the latest server if the endpoint contract changed
- Check that auth cookies/tokens are being sent so the API does not return an alternate payload shape
- If behind a proxy, fix the proxy so real API JSON is passed through instead of a 200 error page
Example fix
// before
const preview = parseGithubPluginImportPreview(await res.json());
// after
const payload: unknown = await res.json();
if (!(isRecord(payload) && isRecord(payload.item))) {
console.error('unexpected preview payload', payload);
throw new Error('GitHub plugin preview response was incomplete.');
}
const preview = parseGithubPluginImportPreview(payload); Defensive patterns
Strategy: type-guard
Validate before calling
function hasGithubPreviewItem(payload: unknown): boolean {
return isRecord(payload) && isRecord(payload.item);
}
// call before parsing: if (!hasGithubPreviewItem(payload)) { handle gracefully; } Type guard
const isGithubPluginImportPreview = (p: unknown): p is { item: Record<string, unknown> } =>
isRecord(p) && isRecord(p.item); Try / catch
try {
const preview = parseGithubPluginImportPreview(payload);
} catch (err) {
showError('Could not load the GitHub plugin preview. Verify the repository and try again.');
console.warn('preview payload rejected', payload);
} Prevention
- Always guard the raw fetch result with isRecord checks before handing it to the parser
- Log unexpected payloads to catch server contract drift early
- Add a contract test asserting the preview endpoint returns { item: {...} }
- Keep web app and den-api deployed in lockstep
When it happens
Trigger: The import-preview fetch resolved with HTTP 200 but the body is not `{ item: {...} }` — e.g. the API returned `{ error: ... }`, an empty object, an HTML error page parsed as text, or a proxy stripped/reshaped the response.
Common situations: Backend contract drift after a den-api deploy; a gateway (nginx/Cloudflare) returning a 200 with an error page; calling the endpoint against an older server that does not return the `item` wrapper; CSRF/auth middleware returning a JSON body without `item`.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- This install link returned incomplete setup details.
- Organization was created, but no slug was returned.
- No OpenWork link was returned.
- Library response was incomplete.
- Endpoint test returned an unexpected response.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/0bbab25c7b000807.
Report an issue: GitHub.