different-ai/openwork · error · DenApiError

extensions.add_unauthorized

extensions.add_unauthorized

Error message

extensions.add_unauthorized

What it means

Thrown by the extensions store when adding a plugin/extension fails because the Den API rejected the request with HTTP 401. The store catches DenApiError with status 401 and rethrows a localized 'extensions.add_unauthorized' message so the settings UI shows a friendly auth error instead of a raw API error. Any other error is rethrown unchanged.

Source

Thrown at apps/app/src/react-app/domains/settings/state/extensions-store.ts:2289

      baseUrl: settings.baseUrl,
      token,
    });
    const body = denLibraryPluginCreateRequest(kind, {
      ...input,
      components: kind === "plugin" ? drafts : input.components,
    });
    try {
      await client.setActiveOrganization({ organizationId: orgId });
      const pluginId = await client.createOrgPlugin(orgId, body);
      await waitForListedLibraryPlugin(
        () => client.listMeLibraryPlugins(orgId),
        pluginId,
      );
      clearCloudInventoryCache();
      return pluginId;
    } catch (error) {
      if (error instanceof DenApiError && error.status === 401) {
        throw new Error(t("extensions.add_unauthorized"));
      }
      throw error;
    }
  }

  function abortRefreshes() {
    refreshSkillsAborted = true;
    refreshPluginsAborted = true;
    refreshCloudOrgMarketplacesAborted = true;
  }

  function ensureSkillsFresh() {
    if (!snapshot.skillsStale) return;
    void refreshSkills({ force: true });
  }

  function ensurePluginsFresh(scopeOverride?: PluginScope) {
    if (!snapshot.pluginsStale) return;

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Re-authenticate with Den (Account → Sign in / paste sign-in code) and retry the add.
  2. Refresh the cloud inventory/token state before retrying (clearCloudInventoryCache runs on success anyway).
  3. Check the plugin's Den API endpoint and token configuration if 401 persists for a freshly signed-in user.

Example fix

// before
throw new Error(t("extensions.add_unauthorized"));
// after — prompt re-auth flow instead of a dead-end error
if (error instanceof DenApiError && error.status === 401) {
  await requestDenSignIn();
  return addPlugin(pluginId); // retry once after re-auth
}
Defensive patterns

Strategy: try-catch

Validate before calling

const authed = await denApi.whoami().then(() => true, () => false);
if (!authed) await requestDenSignIn();

Type guard

function isDenAuthError(e: unknown): e is DenApiError {
  return e instanceof DenApiError && e.status === 401;
}

Try / catch

try {
  await extensionsStore.add(pluginId);
} catch (error) {
  if (error instanceof DenApiError && error.status === 401) {
    await requestDenSignIn(); // re-auth then retry
  } else throw error;
}

Prevention

When it happens

Trigger: Calling the store's add-extension action while the user's Den session token is missing, expired, or revoked; the underlying Den API call (which then calls clearCloudInventoryCache() on success) returns 401.

Common situations: User signed out of Den or their cloud session expired while the settings page stayed open; token rotated server-side; app started without completing cloud sign-in and the user attempts to install a cloud plugin.

Understand the failure class

Related errors


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