{"record":{"id":"4b6a0a9ccd7e769e","repo":"paperclipai/paperclip","slug":"packagename-is-required-and-must-be-a-string-4b6a0a","errorCode":null,"errorMessage":"packageName is required and must be a string","messagePattern":"packageName is required and must be a string","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/src/routes/plugins.ts","lineNumber":1148,"sourceCode":"   * bundled plugin catalog root may be installed. npm/registry installs and\n   * arbitrary local paths are rejected with `403`. Local paths are\n   * canonicalized and validated on every instance.\n   *\n   * Response: `PluginRecord`\n   *\n   * Errors:\n   * - `400` — validation failure or install error (package not found, bad manifest, etc.)\n   * - `403` — install source not permitted on a cloud-managed instance\n   * - `500` — installation succeeded but manifest is missing (indicates a loader bug)\n   */\n  router.post(\"/plugins/install\", async (req, res) => {\n    assertInstanceAdmin(req);\n    assertPluginManagementVisible();\n    const { packageName, version, isLocalPath } = req.body as PluginInstallRequest;\n\n    // Input validation\n    if (!packageName || typeof packageName !== \"string\") {\n      res.status(400).json({ error: \"packageName is required and must be a string\" });\n      return;\n    }\n\n    if (version !== undefined && typeof version !== \"string\") {\n      res.status(400).json({ error: \"version must be a string if provided\" });\n      return;\n    }\n\n    if (isLocalPath !== undefined && typeof isLocalPath !== \"boolean\") {\n      res.status(400).json({ error: \"isLocalPath must be a boolean if provided\" });\n      return;\n    }\n\n    // Validate package name format\n    const trimmedPackage = packageName.trim();\n    if (trimmedPackage.length === 0) {\n      res.status(400).json({ error: \"packageName cannot be empty\" });\n      return;","sourceCodeStart":1130,"sourceCodeEnd":1166,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/routes/plugins.ts#L1130-L1166","documentation":"400 validation guard on POST /plugins/install. Fires when req.body.packageName is missing or not a string; the install endpoint requires a package name (npm package or local path) before any installation step runs.","triggerScenarios":"Thrown at server/src/routes/plugins.ts:1132 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Include the required field(s) in the request path, query, or body as named by the error message, then retry.","Check the API contract in packages/shared validators for the exact required shape of this endpoint."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}