different-ai/openwork · error
Library response was incomplete.
Error message
Library response was incomplete.
What it means
parseLibraryPayload validates the payload returned from GET /v1/me/library before trusting it. If the payload is not a plain object or is missing an `items` array, the library item list is unusable, so it throws this error instead of returning silently-empty data. It is a defensive schema check on the server response.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/library-data.tsx:262
: null;
if (!id || (value.plugin !== null && !plugin) || !name || description === undefined || !role || !edges || !state || !resultState
|| latestSuccessfulAt === undefined || !viewState || activeViewTitle === undefined || !source
|| typeof value.automationCount !== "number" || !Number.isInteger(value.automationCount) || value.automationCount < 0) return null;
return { type: "workflow", id, plugin, name, description, role, edges, state, resultState, latestSuccessfulAt, viewState, activeViewTitle, automationCount: value.automationCount, source };
}
function parseLibraryItem(value: unknown): LibraryItem | null {
if (!isRecord(value)) return null;
if (value.type === "plugin") return parsePlugin(value);
if (value.type === "app") return null;
if (value.type === "connection") return parseConnection(value);
if (value.type === "workflow") return parseWorkflow(value);
return null;
}
export function parseLibraryPayload(payload: unknown): LibraryItem[] {
if (!isRecord(payload) || !Array.isArray(payload.items)) {
throw new Error("Library response was incomplete.");
}
const items = payload.items
.map(parseLibraryItem)
.filter((item): item is LibraryItem => item !== null);
const supportedItemCount = payload.items.filter((item) => !isRecord(item) || item.type !== "app").length;
if (items.length !== supportedItemCount) {
throw new Error("Library response was incomplete.");
}
return items;
}
export function useLibrary() {
return useQuery({
queryKey: libraryQueryKeys.items,
queryFn: async (): Promise<LibraryItem[]> => {
const { response, payload } = await requestJson(
"/v1/me/library",
{ method: "GET" },View on GitHub (pinned to 2b7df46e8a)
Solutions
- Log the raw payload of the /v1/me/library response and confirm it is an object containing `items: []`.
- Check the den-api route handler for /v1/me/library to ensure it returns `{ items: [...] }` on success.
- Verify frontend and backend versions match (no stale deploy or mixed API versions).
- Inspect for proxies/interceptors (service worker, test mocks) rewriting the response body.
- Update the parsing function if the API contract intentionally changed.
Example fix
// before (server returning bare list)
return NextResponse.json(items);
// after (server returning expected envelope)
return NextResponse.json({ items }); Defensive patterns
Strategy: validation
Validate before calling
function isLibraryPayload(p: unknown): p is { items: unknown[] } {
return typeof p === "object" && p !== null && !Array.isArray(p) && Array.isArray((p as { items?: unknown }).items);
}
// call: if (!isLibraryPayload(await res.json())) throw new Error("Library response was incomplete."); Type guard
const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
Try / catch
try {
const items = await fetchLibrary();
} catch (err) {
if (err instanceof Error && err.message === "Library response was incomplete.") {
console.error("Malformed /v1/me/library payload", err);
// show empty-library fallback with a refresh action
} else throw err;
} Prevention
- Add contract tests asserting /v1/me/library returns { items: [] } even when empty.
- Keep frontend parsers and server response shapes versioned together.
- Alert on 200 responses whose body fails schema validation in production telemetry.
- Avoid interceptors/mocks that rewrite JSON response bodies.
When it happens
Trigger: The /v1/me/library endpoint returns 200 but the JSON body is not an object (e.g. null, string, array) or the object lacks an `items` array property (e.g. the server returned an error-shaped body with a 200 status, a proxy stripped the body, or an API contract change renamed `items`).
Common situations: Server deployed an API version where the library payload shape changed; a gateway/CDN returned an HTML error page with status 200; the client hit a different (older/newer) backend than the one the frontend expects; response body intercepted/rewritten by middleware.
Related errors
- Endpoint test returned an unexpected response.
- Provider details were missing from the response.
- Provider details could not be parsed.
- Inference settings response was incomplete.
- Failed to load library (${response.status}).
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/524c4489790398c5.
Report an issue: GitHub.