Skip to content

jitsi-meet: reads .url off the api.http.post wrapper, so every click fails with "No url in response" #11

Description

@Tarek-Elmoursi

Description

jitsi-meet reads the meeting URL directly off the value api.http.post() resolves to, but that value is a wrapper, not the response body. So url is always undefined and every click on Add Jitsi Meeting fails with No url in response — even when the sidecar answered correctly with 200 {"url": "..."}.

Where

jitsi-meet/src/index.js (and the built index.js):

const data = await slotApi.http.post("/api/jitsi", { eventTitle });
const url = data?.url;                       // <- always undefined
if (!url) throw new Error("No url in response");

The host returns a wrapper, in lib/plugin-sandbox/host-api.ts:

const res = await apiFetch(url.pathname + url.search, { method: 'POST', headers, body: requestBody });
const data = await res.json().catch(() => null);
return { ok: res.ok, status: res.status, data };   // <- the body is at .data

So the URL is at result.data.url, not result.url.

Steps to Reproduce

  1. Run a sidecar at /api/jitsi that returns 200 with {"url": "https://meet.example.com/room"}.
  2. Install jitsi-meet (use the main zip — the marketplace build cannot load at all, see [Bug]: Issues enabling external-recipient-warning, jitsi-meet and calendar-agenda #4).
  3. Open a calendar event and click Add Jitsi Meeting.

Expected Behavior

The meeting link is written onto the event.

Actual Behavior

Toast: Could not create Jitsi meeting: No url in response. The sidecar logs a successful 200, so the failure is entirely client-side.

Suggested Fix

Read through the wrapper, tolerating both shapes in case the host contract changes again:

const result = await slotApi.http.post("/api/jitsi", { eventTitle });
const payload = result && result.data !== undefined ? result.data : result;
const url = payload?.url;
if (!url) {
  const status = result?.status ? ` (HTTP ${result.status})` : "";
  const detail = payload?.error ? `: ${payload.error}` : "";
  throw new Error(`the server did not return a meeting link${status}${detail}`);
}

Surfacing result.status is worth doing on its own. The current No url in response is indistinguishable between "the sidecar is not deployed" (404), "the credential was rejected" (401) and "the response shape is wrong" — I chased the wrong one of those three for a while because the message hides the status the host already hands the plugin.

Bulwark Version

1.8.1

Additional Context

Verified against a sidecar returning 200 {"url": ...}: the request arrives and is answered correctly, and the plugin still throws. Applying the change above fixes it with no other modification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions