different-ai/openwork · error

${failureLabel} (${response.status}).

Error message

${failureLabel} (${response.status}).

What it means

postJson in plugin-editor-screen.tsx is a shared helper that POSTs a JSON body and throws getRequestError with a caller-supplied failureLabel when the response is not ok. The message becomes e.g. 'Failed to create Plugin (500).'. It is a generic wrapper: the status code and payload carry the actual diagnostic.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/plugin-editor-screen.tsx:116

    input: {
      rawSourceText:
        component.kind === "skill" ? buildSkillMarkdown(component) : `${component.content.trim()}\n`,
      metadata: {
        name: component.name.trim(),
        description: component.description.trim() || undefined,
      },
    },
  };
}

async function postJson(path: string, body: unknown, failureLabel: string): Promise<unknown> {
  const { response, payload } = await requestJson(
    path,
    { method: "POST", body: JSON.stringify(body) },
    20000,
  );
  if (!response.ok) {
    throw getRequestError(payload, response, `${failureLabel} (${response.status}).`);
  }
  return payload;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null;
}

function createdItemId(payload: unknown): string | null {
  const item = isRecord(payload) && isRecord(payload.item) ? payload.item : null;
  return typeof item?.id === "string" ? item.id : null;
}

export function PluginEditorScreen() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const queryClient = useQueryClient();
  const { orgContext, orgSlug, runReauthableAction } = useOrgDashboard();

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the status in the message and the server payload for field-level validation errors; fix the draft accordingly.
  2. For 401, re-authenticate; for 403, verify plugin-create permission in the org.
  3. If 502/504 or timeout, check Den server health and retry once.
  4. Ensure the plugin name/slug is unique in the org before resubmitting.

Example fix

// before: resubmitting identical draft blindly
await createPlugin(draft);
// after: guard obvious client-side validation first
if (!draft.name?.trim()) throw new Error('Plugin name is required.');
await createPlugin(draft);
Defensive patterns

Strategy: validation

Validate before calling

const errors = validatePluginDraft(draft); // zod schema for name, description, server keys
if (!errors.success) throw new Error('Fix draft errors before creating: ' + errors.error.message);

Type guard

function isPluginDraft(v: unknown): v is { name: string; selectedServerKeys: string[] } {
  return typeof v === 'object' && v !== null &&
    typeof (v as Record<string, unknown>).name === 'string' &&
    Array.isArray((v as Record<string, unknown>).selectedServerKeys);
}

Try / catch

try {
  const item = await createPlugin(draft);
  router.push(`/plugins/${item.id}`);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (/\(400\)/.test(msg)) toast('Check the highlighted fields and resubmit.');
  else if (/\(409\)/.test(msg)) toast('A plugin with this name already exists.');
  else toast(msg);
}

Prevention

When it happens

Trigger: Any createPlugin POST via postJson returning 4xx/5xx: validation failure (400) on plugin draft fields, unauthorized session (401), missing permissions (403), name conflict (409), or gateway error (502/504). 20s request timeout also lands here.

Common situations: Submitting the plugin editor with an invalid draft (missing name/description constraints); duplicated plugin slug; Den API deploy in progress; long-running create exceeding the 20s timeout behind a slow upstream.

Related errors


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