different-ai/openwork · error · DenApiError

invalid_marketplace_payload

invalid_marketplace_payload

Error message

Marketplace response was missing plugin details.

What it means

DenApiError thrown by getOrgMarketplaceResolved in apps/app/src/app/lib/den.ts when GET /v1/marketplaces/{marketplaceId}/resolved returned 2xx but getOrgMarketplaceResolved could not extract the resolved marketplace with its plugin details from the payload. It guards callers against a marketplace object missing plugins/components or being structurally wrong.

Source

Thrown at apps/app/src/app/lib/den.ts:3450

    async listMeLibraryPlugins(orgId: string): Promise<DenMeLibraryPlugin[]> {
      const payload = await requestJson<unknown>(
        baseUrls,
        "/v1/me/library",
        { method: "GET", token, organizationId: orgId },
      );
      return getMeLibraryPlugins(payload);
    },

    async getOrgMarketplaceResolved(orgId: string, marketplaceId: string): Promise<DenOrgMarketplaceResolved> {
      const payload = await requestJson<unknown>(
        baseUrls,
        `/v1/marketplaces/${encodeURIComponent(marketplaceId)}/resolved`,
        { method: "GET", token, organizationId: orgId },
      );
      const resolved = getOrgMarketplaceResolved(payload);
      if (!resolved) {
        throw new DenApiError(500, "invalid_marketplace_payload", "Marketplace response was missing plugin details.");
      }
      return resolved;
    },

    async getOrgPluginResolved(orgId: string, plugin: DenOrgPlugin): Promise<DenOrgPluginResolved> {
      const payload = await requestJson<unknown>(
        baseUrls,
        `/v1/plugins/${encodeURIComponent(plugin.id)}/resolved`,
        { method: "GET", token, organizationId: orgId },
      );
      return getOrgPluginResolved(plugin, payload);
    },

    async createOrgPlugin(
      orgId: string,
      input: {
        name: string;
        description?: string | null;

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the raw JSON from /v1/marketplaces/:id/resolved and compare with the fields getOrgMarketplaceResolved expects
  2. Verify the marketplaceId belongs to the org and has published plugins (check via /v1/marketplaces?status=active)
  3. Align server and client versions — a resolved-schema drift means upgrade one side
  4. Bypass any caching proxy to rule out a stale/mangled cached body
  5. Re-fetch after re-authenticating if the response could be a limited-permission stub

Example fix

// before
const resolved = getOrgMarketplaceResolved(payload);
if (!resolved) {
  throw new DenApiError(500, "invalid_marketplace_payload", "Marketplace response was missing plugin details.");
}
// after
caller-side guard:
try {
  const resolved = await client.getOrgMarketplaceResolved(orgId, marketplaceId);
} catch (err) {
  if (err instanceof DenApiError && err.code === "invalid_marketplace_payload") {
    // fall back to listOrgMarketplaces to verify the marketplace id/state
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-check the marketplace exists and is active
const marketplaces = await client.listOrgMarketplaces(orgId);
if (!marketplaces.some((m) => m.id === marketplaceId)) {
  throw new Error(`Marketplace not found or inactive: ${marketplaceId}`);
}

Type guard

function isResolvedMarketplace(v: unknown): v is DenOrgMarketplaceResolved {
  return (
    typeof v === "object" && v !== null &&
    "id" in v && "plugins" in v && Array.isArray((v as { plugins?: unknown }).plugins)
  );
}

Try / catch

try {
  const resolved = await client.getOrgMarketplaceResolved(orgId, marketplaceId);
} catch (err) {
  if (err instanceof DenApiError && err.code === "invalid_marketplace_payload") {
    // fall back to listOrgMarketplaces or show an empty marketplace state
  } else { throw err; }
}

Prevention

When it happens

Trigger: The /resolved endpoint responds 200 with null/empty data (marketplace empty or unpublished), the body lacks the plugin detail fields the parser requires, or the server's resolved-marketplace schema differs from what this client version expects.

Common situations: Self-hosted Den server running an older schema for /v1/marketplaces/:id/resolved; a marketplace that exists but has no published plugins yet; wrong marketplaceId in a saved config resolving to a stub; a proxy caching or mangling the response.

Related errors


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