bmad-code-org/BMAD-METHOD · error · Error
--set "${entry}": empty module or key. Expected <module>.<ke
Error message
--set "${entry}": empty module or key. Expected <module>.<key>=<value> What it means
Thrown by parseSetEntry when the LHS splits on '.' but either side trims to empty. The format requires both module and key to be non-empty identifiers; whitespace-only or missing segments are rejected.
Source
Thrown at tools/installer/set-overrides.js:55
throw new Error('--set: empty entry. Expected <module>.<key>=<value>');
}
const eq = entry.indexOf('=');
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>>}
*/View on GitHub (pinned to b70486b9bd)
Solutions
- Ensure both the module and key segments are non-empty identifiers.
- Remove stray dots or stray whitespace around the dot.
- If generating args from a template, validate each field is populated before emitting.
Example fix
# before # --set .project_knowledge=research # empty module # --set bmm.=research # empty key # # after # --set bmm.project_knowledge=research
Defensive patterns
Strategy: validation
Validate before calling
function hasNonEmptyModuleAndKey(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;
return lhs.slice(0, dot).trim().length > 0 && lhs.slice(dot + 1).trim().length > 0;
}
const entries = raw.filter(hasNonEmptyModuleAndKey); Type guard
function isValidSetEntry(entry) {
return typeof entry === 'string' && /^[^.\s]+\.[^.\s]+=.+$/.test(entry);
} Try / catch
try {
overrides = parseSetEntries(entries);
} catch (e) {
if (/empty module or key/.test(e.message)) {
// strip entries with stray dots/whitespace and retry
} else { throw e; }
} Prevention
- Trim and validate both segments of the LHS in your wrapper before emitting --set.
- Avoid leading/trailing dots and whitespace in module/key identifiers.
When it happens
Trigger: Passing --set .key=value (empty module), --set module.=value (empty key), or --set module. =value (whitespace-only key).
Common situations: Leading/trailing dot typo; whitespace sneaking in via copy-paste; a templating layer emitting 'module.${field}' with field unset.
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}": '__proto__', 'prototype', and 'constructor
- Invalid action: ${options.action}. Valid actions: ${validAct
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/b02d22cc72cfdbb8.
Report an issue: GitHub.