{"record":{"id":"fc8f7236ed5a16da","repo":"Hmbown/CodeWhale","slug":"parallel-max-max-items-items-per-call","errorCode":null,"errorMessage":"parallel(): max ${MAX_ITEMS} items per call","messagePattern":"parallel\\(\\): max (.+?) items per call","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/workflow-js/src/vm.rs","lineNumber":1076,"sourceCode":"  };\n\n  globalThis.task = async (opts) => {\n    if (opts === null || typeof opts !== \"object\") {\n      throw new TypeError(\"task(): expected an options object\");\n    }\n    const envelope = JSON.parse(await hostTask(JSON.stringify(opts)));\n    if (envelope.error !== undefined) {\n      throw new Error(envelope.error);\n    }\n    return envelope.value;\n  };\n\n  globalThis.parallel = (thunks) => {\n    if (!Array.isArray(thunks)) {\n      throw new TypeError(\"parallel(): expected an array of thunks\");\n    }\n    if (thunks.length > MAX_ITEMS) {\n      throw new Error(\"parallel(): max \" + MAX_ITEMS + \" items per call\");\n    }\n    return Promise.all(thunks.map((thunk) => {\n      try {\n        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)) {","sourceCodeStart":1058,"sourceCodeEnd":1094,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/workflow-js/src/vm.rs#L1058-L1094","documentation":"After place() copies the staged bundle into its final directory under the user plugins dir, resolve_manifest_path fails to find any of plugin.json, kimi.plugin.json, or plugin.toml at the bundle root. This is a post-copy integrity check: the manifest existed during staging (validate_staged passed), but the final tree does not have one at its root. The installer rolls back — it removes the copied directory and restores any backup it took — so no half-installed plugin remains.","triggerScenarios":"A race where the staged tree changes between staging and copy; a bundle whose manifest sits in a nested subdirectory so the copy lands the manifest below the root; an install pipeline that rewrites/repacks the staged tree and drops the manifest.","commonSituations":"Installing from a git checkout or tarball where the plugin lives in a subdirectory and the wrong root was staged; concurrent plugin installs mutating the same staging area; packaging scripts that exclude the manifest (e.g. .gitignore-style filtering applied to plugin.json).","solutions":["Verify the bundle layout: the directory you install must contain plugin.json (or kimi.plugin.json / plugin.toml) directly at its root, not one level down.","Re-run the install — the rollback already cleaned the bad copy, and a transient staging race is resolved by a fresh stage.","If building the bundle yourself, ensure the manifest is copied into the archive/checkout root and not filtered out."],"exampleFix":"# before: repo root staged, manifest lives in ./plugins/my-plugin/plugin.json\nplugin install ./my-plugin-repo\n\n# after: stage the bundle directory that actually holds the manifest\nplugin install ./my-plugin-repo/plugins/my-plugin","handlingStrategy":"validation","validationCode":"// before installing, confirm the bundle you ship actually has a root manifest\nlet manifest_ok = [\"plugin.json\", \"kimi.plugin.json\", \"plugin.toml\"]\n    .iter().any(|m| final_bundle_dir.join(m).is_file());\nassert!(manifest_ok, \"bundle must keep its manifest at the root after copy\");","typeGuard":"fn has_root_manifest(bundle: &Path) -> bool {\n    [\"plugin.json\", \"kimi.plugin.json\", \"plugin.toml\"].iter()\n        .any(|m| bundle.join(m).is_file())\n}","tryCatchPattern":"match install_plugin(source).await {\n    Ok(rec) => rec,\n    Err(e) if e.to_string().contains(\"installed plugin has no supported manifest\") => {\n        // rollback already ran; fix the bundle layout and retry the install once\n        return Err(e).context(\"bundle layout lost its root manifest during copy\"));\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep the manifest at the bundle root in every packaging step; test the packaged artifact, not the source tree.","Do not filter plugin.json/kimi.plugin.json/plugin.toml out of archives or copy scripts.","Avoid concurrent installs into the same plugins directory; serialize installs.","Rely on the built-in rollback: after this error, clean up and retry rather than leaving partial state."],"tags":["rust","plugins","install","manifest","integrity"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}