different-ai/openwork · error · RemoteMcpAppError

plugin_not_found

plugin_not_found

Error message

Plugin not found.

What it means

importRemoteMcpApp accepts an optional pluginId to attach the imported app to a plugin. If that id is not a valid den plugin id, normalizeDenTypeId throws and a 404 plugin_not_found is raised before any outbound download happens, so invalid targets fail fast.

Source

Thrown at ee/apps/den-api/src/remote-mcp-apps.ts:442

      csp: { connectDomains: [], resourceDomains: [], frameDomains: [], baseUriDomains: [] },
    },
    diagnostics: fetched.diagnostics,
  }
}

export async function importRemoteMcpApp(input: {
  context: PluginArchActorContext
  pluginId?: string
  sourceUrl: string
  activate?: boolean
  requireFreshSession?: boolean
}) {
  let pluginId: DenTypeId<"plugin"> | null = null
  if (input.pluginId) {
    try {
      pluginId = normalizeDenTypeId("plugin", input.pluginId)
    } catch {
      throw new RemoteMcpAppError(404, "plugin_not_found", "Plugin not found.")
    }
    // Reject an unavailable target before performing any outbound download.
    await requirePluginArchResourceRole({
      context: input.context,
      requireFreshSession: input.requireFreshSession,
      resourceId: pluginId,
      resourceKind: "plugin",
      role: "editor",
    })
  }
  const fetched = await fetchRemoteMcpApp(input.sourceUrl)
  if (!pluginId) {
    const plugin = await createPlugin({
      context: input.context,
      name: fetched.metadata.name,
      description: fetched.metadata.description,
      sourceRepositoryUrl: fetched.sourceUrl.length <= 1024 ? fetched.sourceUrl : null,
    })

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Pass the plugin's actual den plugin id (as returned by plugin create/list endpoints), not a configObject id.
  2. List plugins in your organization to get a fresh valid pluginId.
  3. Omit pluginId entirely if you do not intend to attach the app to a plugin.
  4. Check the id is not truncated or double-encoded in your client code.
Defensive patterns

Strategy: validation

Validate before calling

import { normalizeDenTypeId } from "./ids.js";
try { normalizeDenTypeId("plugin", pluginId); }
catch { throw new Error("Invalid plugin id before importing remote MCP app"); }

Type guard

function isPluginId(id: string): boolean {
  try { normalizeDenTypeId("plugin", id); return true; } catch { return false; }
}

Try / catch

try {
  await importRemoteMcpApp({ context, sourceUrl, pluginId });
} catch (e) {
  if (e instanceof RemoteMcpAppError && e.code === "plugin_not_found") {
    // pluginId malformed or not a plugin id; look up the correct id and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling importRemoteMcpApp with input.pluginId set to a value that fails plugin id normalization: a configObject id, a malformed/truncated id, or an id from a different identifier namespace.

Common situations: Passing the remote MCP app's configObject id instead of the plugin id; stale plugin ids after the plugin was deleted; client-side typos or slug vs id confusion in scripts.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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