jackwener/OpenCLI · error

Updated source is no longer a monorepo: ${cloneUrl}

Error message

Updated source is no longer a monorepo: ${cloneUrl}

What it means

During updatePlugin() of a monorepo sub-plugin, the library re-clones the monorepo into a temp dir and re-reads its manifest. If the upstream repo no longer has a monorepo-shaped manifest (readPluginManifest returns null or isMonorepo is false), the update cannot proceed through the monorepo path, so it throws. This protects against upstream restructuring that would silently break sub-plugin lifecycle tracking.

Source

Thrown at src/plugin.ts:1125

  }

  const lock = readLockFile();
  const lockEntry = lock[name];
  const source = resolvePluginSource(lockEntry, targetDir);

  if (source?.kind === 'local') {
    updateLocalPlugin(name, targetDir, lock, lockEntry);
    return;
  }

  if (source?.kind === 'monorepo') {
    const monoDir = path.join(getMonoreposDir(), source.repoName);
    const monoName = source.repoName;
    const cloneUrl = source.url;
    withTempClone(cloneUrl, (tmpCloneDir) => {
      const manifest = readPluginManifest(tmpCloneDir);
      if (!manifest || !isMonorepo(manifest)) {
        throw new Error(`Updated source is no longer a monorepo: ${cloneUrl}`);
      }

      if (manifest.opencli && !checkCompatibility(manifest.opencli)) {
        throw new Error(
          `Plugin requires opencli ${manifest.opencli}, but current version is incompatible.`
        );
      }

      const updatedPlugins = collectUpdatedMonorepoPlugins(
        monoName,
        lock,
        manifest,
        cloneUrl,
        tmpCloneDir,
      );

      if (updatedPlugins.length > 0) {
        postInstallMonorepoLifecycle(

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the upstream repo at cloneUrl: if it is now a standalone plugin, uninstall the sub-plugin and install it as a standalone plugin instead.
  2. Pin the update to a commit/tag/branch where the monorepo structure still exists via the lock entry source.
  3. If the manifest was accidentally removed upstream, restore it and push, then re-run updatePlugin.
  4. Coordinate with the monorepo maintainers before restructuring; migrate sub-plugins explicitly.
Defensive patterns

Strategy: try-catch

Validate before calling

// Peek at the upstream manifest before updating a monorepo sub-plugin:
// withTempClone(source.url, (tmp) => {
//   const m = readPluginManifest(tmp);
//   if (!m || !isMonorepo(m)) migrateToStandalone();
//   else updatePlugin(name);
// });

Try / catch

try {
  updatePlugin(name);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Updated source is no longer a monorepo:")) {
    // uninstall sub-plugin and reinstall as standalone from the new source
  } else throw e;
}

Prevention

When it happens

Trigger: Running updatePlugin on a plugin whose lock entry resolves to a monorepo source, where the freshly cloned repo at cloneUrl has no valid plugin manifest or the manifest is not a monorepo (sub-plugins were removed, repo converted to a standalone plugin, or manifest file deleted upstream).

Common situations: Upstream repository restructured from a multi-plugin monorepo into a single standalone plugin; manifest (e.g. plugin.json / package markers) renamed or removed; cloned a branch/tag where monorepo support was dropped.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b1fb6eb5154659f7. Report an issue: GitHub.