bmad-code-org/BMAD-METHOD · error · Error
--set "${entry}": '__proto__', 'prototype', and 'constructor
Error message
--set "${entry}": '__proto__', 'prototype', and 'constructor' are reserved and cannot be used as a module or key name. What it means
Thrown by parseSetEntry when the module code or key is one of __proto__, prototype, or constructor (the PROTOTYPE_POLLUTING_NAMES set). parseSetEntries assigns overrides into plain-object maps keyed by user input; these names would mutate Object.prototype and cascade into every object lookup. Rejected at parse time as defense-in-depth — the maps are also Object.create(null).
Source
Thrown at tools/installer/set-overrides.js:58
if (eq === -1) {
throw new Error(`--set "${entry}": missing '='. Expected <module>.<key>=<value>`);
}
const lhs = entry.slice(0, eq);
// Note: only the LHS is trimmed. Values may legitimately contain leading
// or trailing whitespace (paths with spaces, quoted strings); module / key
// names cannot, so it's safe to be strict on the left.
const value = entry.slice(eq + 1);
const dot = lhs.indexOf('.');
if (dot === -1) {
throw new Error(`--set "${entry}": missing '.'. Expected <module>.<key>=<value>`);
}
const moduleCode = lhs.slice(0, dot).trim();
const key = lhs.slice(dot + 1).trim();
if (!moduleCode || !key) {
throw new Error(`--set "${entry}": empty module or key. Expected <module>.<key>=<value>`);
}
if (PROTOTYPE_POLLUTING_NAMES.has(moduleCode) || PROTOTYPE_POLLUTING_NAMES.has(key)) {
throw new Error(
`--set "${entry}": '__proto__', 'prototype', and 'constructor' are reserved and cannot be used as a module or key name.`,
);
}
return { module: moduleCode, key, value };
}
/**
* Parse repeated `--set` entries into a `{ module: { key: value } }` map.
* Later entries overwrite earlier ones for the same key. Both the outer
* map and the per-module inner maps are `Object.create(null)` so callers
* that bypass `parseSetEntry`'s name check still can't pollute prototypes.
*
* @param {string[]} entries
* @returns {Object<string, Object<string, string>>}
*/
function parseSetEntries(entries) {
const overrides = Object.create(null);
if (!Array.isArray(entries)) return overrides;View on GitHub (pinned to b70486b9bd)
Solutions
- Choose a module or key name that isn't __proto__, prototype, or constructor.
- If --set args are generated from external data, sanitize/reserved-filter upstream before passing them to the CLI.
Example fix
# before # --set module.constructor=y # # after # --set module.ctor=y
Defensive patterns
Strategy: validation
Validate before calling
const RESERVED = new Set(['__proto__', 'prototype', 'constructor']);
function isSafeSetEntry(entry) {
const eq = entry.indexOf('='); if (eq === -1) return false;
const lhs = entry.slice(0, eq);
const dot = lhs.indexOf('.'); if (dot === -1) return false;
const mod = lhs.slice(0, dot).trim();
const key = lhs.slice(dot + 1).trim();
return !RESERVED.has(mod) && !RESERVED.has(key);
}
const entries = raw.filter(isSafeSetEntry); Type guard
function isSafeSetEntry(entry) {
const RESERVED = new Set(['__proto__', 'prototype', 'constructor']);
if (typeof entry !== 'string') return false;
const m = entry.match(/^([^.=]+)\.([^.=]+)=/);
return !!m && !RESERVED.has(m[1]) && !RESERVED.has(m[2]);
} Try / catch
try {
overrides = parseSetEntries(entries);
} catch (e) {
if (/reserved and cannot be used/.test(e.message)) {
// drop the offending entry; it's either hostile input or a naming mistake
} else { throw e; }
} Prevention
- Sanitize --set args from external/untrusted sources upstream.
- Treat this error as a security signal — investigate where the reserved name came from.
When it happens
Trigger: Passing --set __proto__.x=1, --set module.constructor=y, or --set prototype.key=val. Any override whose module or key segment equals one of the reserved names.
Common situations: Adversarial/fuzzed CLI input; a generated script feeding arbitrary strings as keys; misunderstanding the format and using a JS built-in as a name; attempting prototype pollution deliberately (this is the guard working).
Related errors
- --set: empty entry. Expected <module>.<key>=<value>
- --set "${entry}": missing '='. Expected <module>.<key>=<valu
- --set "${entry}": missing '.'. Expected <module>.<key>=<valu
- --set "${entry}": empty module or key. Expected <module>.<ke
- Unsafe ref name: ${JSON.stringify(ref)}
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/1171e610766dbeb3.
Report an issue: GitHub.