{"record":{"id":"dbf75dfbad82aec6","repo":"davila7/claude-code-templates","slug":"warning-error-loading-plugin-permissions-for-pl","errorCode":null,"errorMessage":"Warning: Error loading plugin permissions for ${plugin.name}","messagePattern":"Warning: Error loading plugin permissions for (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli-tool/src/plugin-dashboard.js","lineNumber":533,"sourceCode":"          }\n        }\n      }\n\n      // Load plugin MCPs\n      const mcpFile = path.join(plugin.path, '.mcp.json');\n      if (await fs.pathExists(mcpFile)) {\n        const mcpData = JSON.parse(await fs.readFile(mcpFile, 'utf8'));\n        for (const [name, config] of Object.entries(mcpData.mcpServers || {})) {\n          permissions.mcps.push({\n            name,\n            source: 'Plugin',\n            plugin: plugin.name,\n            config\n          });\n        }\n      }\n    } catch (error) {\n      console.warn(chalk.yellow(`Warning: Error loading plugin permissions for ${plugin.name}`), error.message);\n    }\n\n    return permissions;\n  }\n\n  setupWebServer() {\n    // Add CORS middleware\n    this.app.use((req, res, next) => {\n      res.header('Access-Control-Allow-Origin', '*');\n      res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n      res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');\n\n      if (req.method === 'OPTIONS') {\n        res.sendStatus(200);\n        return;\n      }\n\n      next();","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-tool/src/plugin-dashboard.js#L515-L551","documentation":"loadPluginPermissions loads a single plugin's permission settings file (plugin.name.json or equivalent under the plugin's config area) and warns when that read/parse or per-entry processing fails. The warning names the offending plugin, which is the key diagnostic. It returns whatever permission entries were parsed before the failure.","triggerScenarios":"Calling loadPluginPermissions for a plugin whose permissions/settings file is invalid JSON, contains permission entries with a shape other than the expected {plugin, config} records, or lives in an unreadable directory (permission bits, dangling symlink).","commonSituations":"A plugin's settings file corrupted during install/update; plugin author shipped a permissions file in an older format; leftover files from an uninstalled plugin whose directory was partially deleted.","solutions":["Open the plugin's permissions/settings file named in the warning and validate it with `jq .`","Fix or delete the corrupt file (it can be regenerated by re-enabling/reinstalling the plugin)","Reinstall the plugin from its marketplace to restore pristine config","Verify directory permissions with `ls -la` on the plugin's config path if parsing is fine"],"exampleFix":"// before\n[ { \"plugin\": \"my-plugin\", \"config\": undefined } ]\n// after\n[ { \"plugin\": \"my-plugin\", \"config\": { \"allowed\": [\"Bash(git:*)\"] } } ]","handlingStrategy":"validation","validationCode":"async function pluginPermFileOk(file) {\n  if (!(await fs.pathExists(file))) return true;\n  try {\n    const arr = JSON.parse(await fs.readFile(file, 'utf8'));\n    return Array.isArray(arr);\n  } catch { return false; }\n}","typeGuard":"function isPermissionEntry(e) {\n  return e != null && typeof e === 'object' && typeof e.plugin === 'string' && e.config != null;\n}","tryCatchPattern":"catch (error) {\n  console.warn(`Permissions for ${plugin.name} unavailable: ${error.message}`);\n  return permissions; // partial entries already collected\n}","preventionTips":["Uninstall plugins through the CLI, never by deleting folders","Validate plugin config files after plugin updates","Treat per-plugin failures as non-fatal; surface the plugin name in UI"],"tags":["plugin","permissions","json-parse","claude-code"],"backgroundTag":"plugin-config-invalid","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}