Hmbown/CodeWhale · error · Error

pipeline(): max ${MAX_ITEMS} items per call

Error message

pipeline(): max ${MAX_ITEMS} items per call

What it means

validate_staged's first check is to locate the manifest of the freshly staged tree: resolve_manifest_path accepts only plugin.json, kimi.plugin.json (Kimi Code compatibility), or plugin.toml at the staged root, in that precedence. If none of the three exists at the top level, the staged copy is rejected before validation or copying proceeds. This usually means the source's manifest sat in a subdirectory that got flattened, dropped, or renamed on the way into staging.

Source

Thrown at crates/workflow-js/src/vm.rs:1098

        return Promise.resolve(typeof thunk === "function" ? thunk() : thunk).catch((err) => {
          if (isFatalTaskError(err)) throw err;
          hostLog("parallel(): dropped a failed slot as null: " + String((err && err.message) || err));
          return null;
        });
      } catch (err) {
        if (isFatalTaskError(err)) return Promise.reject(err);
        hostLog("parallel(): dropped a failed slot as null: " + String((err && err.message) || err));
        return null;
      }
    }));
  };

  globalThis.pipeline = (items, ...stages) => {
    if (!Array.isArray(items)) {
      throw new TypeError("pipeline(): expected an array of items");
    }
    if (items.length > MAX_ITEMS) {
      throw new Error("pipeline(): max " + MAX_ITEMS + " items per call");
    }
    return Promise.all(items.map(async (item, index) => {
      let value = item;
      for (const stage of stages) {
        try {
          value = await stage(value, item, index);
        } catch (err) {
          if (isFatalTaskError(err)) throw err;
          hostLog("pipeline(): dropped item " + index + " as null: " + String((err && err.message) || err));
          return null;
        }
      }
      return value;
    }));
  };

  globalThis.log = (message) => {
    hostLog(typeof message === "string" ? message : (JSON.stringify(message) ?? String(message)));

View on GitHub (pinned to 8880682c63)

Solutions

  1. Re-check the staged/root layout: the bundle directory passed to install must directly contain plugin.json, kimi.plugin.json, or plugin.toml.
  2. If your archive has a wrapper folder, point the install at <extract-dir>/<wrapper>/ so the manifest lands at the root.
  3. If you maintain the bundle, name the manifest one of the three supported files and keep it at the root; do not symlink it.

Example fix

# before: bundle root has the manifest nested
bundle/
  src/plugin.json   <- staged root 'bundle' has no manifest -> error

# after
bundle/
  plugin.json
  src/...
Defensive patterns

Strategy: validation

Validate before calling

if crate::plugins::agent_plugin::resolve_manifest_path(source).is_none() {
    anyhow::bail!(
        "{} has no plugin.json/kimi.plugin.json/plugin.toml at its root — pass the bundle directory itself",
        source.display()
    );
}

Type guard

fn is_plugin_bundle(dir: &Path) -> bool {
    crate::plugins::agent_plugin::resolve_manifest_path(dir).is_some()
}

Try / catch

match validate_staged(&staged_path) {
    Ok((name, hash)) => (name, hash),
    Err(e) if e.to_string().contains("staged bundle has no plugin.json") =>
        return Err(e).context("bundle layout must keep a root manifest through staging"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Installing a bundle whose manifest lives one level below the root (repo-style layout); packaging pipelines or tarball prefix-stripping that moves/removes plugin.json; a bundle shipping only an unsupported manifest filename (e.g. manifest.json); a manifest that is a symlink or non-regular file, which is_file() rejects.

Common situations: git clone of a monorepo where the plugin lives in a subdirectory; zips with wrapper folders whose stripping logic removes the wrong level; .gitignore-style copy filters excluding the manifest; bundles authored for other plugin ecosystems with different manifest names.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/e5b2f971a813638c. Report an issue: GitHub.