{"record":{"id":"e5b2f971a813638c","repo":"Hmbown/CodeWhale","slug":"pipeline-max-max-items-items-per-call","errorCode":null,"errorMessage":"pipeline(): max ${MAX_ITEMS} items per call","messagePattern":"pipeline\\(\\): max (.+?) items per call","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/workflow-js/src/vm.rs","lineNumber":1098,"sourceCode":"        return Promise.resolve(typeof thunk === \"function\" ? thunk() : thunk).catch((err) => {\n          if (isFatalTaskError(err)) throw err;\n          hostLog(\"parallel(): dropped a failed slot as null: \" + String((err && err.message) || err));\n          return null;\n        });\n      } catch (err) {\n        if (isFatalTaskError(err)) return Promise.reject(err);\n        hostLog(\"parallel(): dropped a failed slot as null: \" + String((err && err.message) || err));\n        return null;\n      }\n    }));\n  };\n\n  globalThis.pipeline = (items, ...stages) => {\n    if (!Array.isArray(items)) {\n      throw new TypeError(\"pipeline(): expected an array of items\");\n    }\n    if (items.length > MAX_ITEMS) {\n      throw new Error(\"pipeline(): max \" + MAX_ITEMS + \" items per call\");\n    }\n    return Promise.all(items.map(async (item, index) => {\n      let value = item;\n      for (const stage of stages) {\n        try {\n          value = await stage(value, item, index);\n        } catch (err) {\n          if (isFatalTaskError(err)) throw err;\n          hostLog(\"pipeline(): dropped item \" + index + \" as null: \" + String((err && err.message) || err));\n          return null;\n        }\n      }\n      return value;\n    }));\n  };\n\n  globalThis.log = (message) => {\n    hostLog(typeof message === \"string\" ? message : (JSON.stringify(message) ?? String(message)));","sourceCodeStart":1080,"sourceCodeEnd":1116,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/workflow-js/src/vm.rs#L1080-L1116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-check the staged/root layout: the bundle directory passed to install must directly contain plugin.json, kimi.plugin.json, or plugin.toml.","If your archive has a wrapper folder, point the install at <extract-dir>/<wrapper>/ so the manifest lands at the root.","If you maintain the bundle, name the manifest one of the three supported files and keep it at the root; do not symlink it."],"exampleFix":"# before: bundle root has the manifest nested\nbundle/\n  src/plugin.json   <- staged root 'bundle' has no manifest -> error\n\n# after\nbundle/\n  plugin.json\n  src/...","handlingStrategy":"validation","validationCode":"if crate::plugins::agent_plugin::resolve_manifest_path(source).is_none() {\n    anyhow::bail!(\n        \"{} has no plugin.json/kimi.plugin.json/plugin.toml at its root — pass the bundle directory itself\",\n        source.display()\n    );\n}","typeGuard":"fn is_plugin_bundle(dir: &Path) -> bool {\n    crate::plugins::agent_plugin::resolve_manifest_path(dir).is_some()\n}","tryCatchPattern":"match validate_staged(&staged_path) {\n    Ok((name, hash)) => (name, hash),\n    Err(e) if e.to_string().contains(\"staged bundle has no plugin.json\") =>\n        return Err(e).context(\"bundle layout must keep a root manifest through staging\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Point installs at the directory that directly contains plugin.json, not a checkout or archive root.","Do not filter plugin.json/kimi.plugin.json/plugin.toml out of archives or copy scripts.","Never symlink the manifest; ship it as a regular file at the bundle root.","Check staged bundles (not just sources) with resolve_manifest_path before validation."],"tags":["rust","plugins","install","manifest","staging"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}