Mintplex-Labs/anything-llm · error · Error
Plugin handler does not pass path validation.
Error message
Plugin handler does not pass path validation.
What it means
Thrown in the ImportedPlugin constructor (server/utils/agents/imported.js:20) when the resolved handler.js location is not within the plugins/agent-skills directory (isWithin returns false). It is a path-traversal guard (CWE-22) that runs after normalizePath on config.hubId, blocking hubIds containing '..' or absolute paths from escaping the plugin sandbox before the require() call.
Source
Thrown at server/utils/agents/imported.js:21
const { safeJsonParse } = require("../http");
const { isWithin, normalizePath } = require("../files");
const { CollectorApi } = require("../collectorApi");
const pluginsPath =
process.env.NODE_ENV === "development"
? path.resolve(__dirname, "../../storage/plugins/agent-skills")
: path.resolve(process.env.STORAGE_DIR, "plugins", "agent-skills");
const sharedWebScraper = new CollectorApi();
class ImportedPlugin {
constructor(config) {
this.config = config;
this.handlerLocation = path.resolve(
pluginsPath,
normalizePath(this.config.hubId),
"handler.js"
);
if (!isWithin(pluginsPath, this.handlerLocation))
throw new Error("Plugin handler does not pass path validation.");
delete require.cache[require.resolve(this.handlerLocation)];
this.handler = require(this.handlerLocation);
this.name = config.hubId;
this.startupConfig = {
params: {},
};
}
/**
* Gets the imported plugin handler.
* @param {string} hubId - The hub ID of the plugin.
* @returns {ImportedPlugin} - The plugin handler.
*/
static loadPluginByHubId(hubId) {
const configLocation = path.resolve(
pluginsPath,
normalizePath(hubId),
"plugin.json"View on GitHub (pinned to 526360e320)
Solutions
- Sanitize hubId to a single safe folder name (e.g. ^[a-z0-9-_]+$) before constructing the plugin.
- Regenerate the offending plugin's plugin.json with a clean hubId, or delete and re-import it.
- Confirm STORAGE_DIR is set correctly so pluginsPath resolves to the intended directory.
Example fix
// before
const plugin = new ImportedPlugin({ hubId: req.body.hubId });
// after
if (!/^[a-z0-9-_]+$/i.test(req.body.hubId)) return res.status(400).send('invalid hubId');
const plugin = new ImportedPlugin({ hubId: req.body.hubId }); Defensive patterns
Strategy: validation
Validate before calling
function safeHubId(hubId) {
return typeof hubId === 'string' && /^[a-z0-9-_]+$/i.test(hubId) && !hubId.includes('..');
}
if (!safeHubId(config.hubId)) throw new Error('Invalid hubId'); Try / catch
try { const p = new ImportedPlugin(config); } catch (e) { if (/path validation/.test(e.message)) return rejectPlugin('unsafe hubId'); throw e; } Prevention
- Validate hubId against a strict allow-list regex before any file operation.
- Never pass raw user input as a path component.
- Keep isWithin as defense-in-depth after normalization.
When it happens
Trigger: new ImportedPlugin(config) or ImportedPlugin.loadPluginByHubId(hubId) with a hubId containing traversal sequences ('..'), an absolute path, or a symlink that resolves outside pluginsPath.
Common situations: Corrupted/tampered plugin.json with a malicious hubId; manually renamed plugin folders; a community plugin whose hubId was crafted; STORAGE_DIR mis-set so even valid hubIds resolve outside the expected directory.
Related errors
- [ImportedPlugin.importCommunityItemFromUrl]: Entry "${entry.
- Invalid path.
- Invalid path name
- Invalid folder name.
- No plugin hubID passed.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/0764b21678cdaaae.
Report an issue: GitHub.