{"record":{"id":"d2834197f0991cbd","repo":"bmad-code-org/BMAD-METHOD","slug":"set-empty-entry-expected-module-key-value","errorCode":null,"errorMessage":"--set: empty entry. Expected <module>.<key>=<value>","messagePattern":"--set: empty entry\\. Expected <module>\\.<key>=<value>","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/set-overrides.js","lineNumber":37,"sourceCode":"// assigns into plain `{}` maps keyed by user input, so `--set __proto__.x=1`\n// would otherwise reach `overrides.__proto__[x] = 1` and pollute every plain\n// object. We reject the names at parse time and harden the maps in\n// `parseSetEntries` with `Object.create(null)` for defense-in-depth.\nconst PROTOTYPE_POLLUTING_NAMES = new Set(['__proto__', 'prototype', 'constructor']);\n\nconst path = require('node:path');\nconst fs = require('./fs-native');\nconst yaml = require('yaml');\n\n/**\n * Parse a single `--set <module>.<key>=<value>` entry.\n * @param {string} entry - raw flag value\n * @returns {{module: string, key: string, value: string}}\n * @throws {Error} on malformed input\n */\nfunction parseSetEntry(entry) {\n  if (typeof entry !== 'string' || entry.length === 0) {\n    throw new Error('--set: empty entry. Expected <module>.<key>=<value>');\n  }\n  const eq = entry.indexOf('=');\n  if (eq === -1) {\n    throw new Error(`--set \"${entry}\": missing '='. Expected <module>.<key>=<value>`);\n  }\n  const lhs = entry.slice(0, eq);\n  // Note: only the LHS is trimmed. Values may legitimately contain leading\n  // or trailing whitespace (paths with spaces, quoted strings); module / key\n  // names cannot, so it's safe to be strict on the left.\n  const value = entry.slice(eq + 1);\n  const dot = lhs.indexOf('.');\n  if (dot === -1) {\n    throw new Error(`--set \"${entry}\": missing '.'. Expected <module>.<key>=<value>`);\n  }\n  const moduleCode = lhs.slice(0, dot).trim();\n  const key = lhs.slice(dot + 1).trim();\n  if (!moduleCode || !key) {\n    throw new Error(`--set \"${entry}\": empty module or key. Expected <module>.<key>=<value>`);","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/set-overrides.js#L19-L55","documentation":"Thrown by parseSetEntry when the --set value is not a string or is empty. Every --set entry must match <module>.<key>=<value>; an empty/missing value gives no module, key, or value to parse and is rejected up front rather than producing a confusing downstream failure.","triggerScenarios":"Passing --set '' to the CLI; calling parseSetEntry('') programmatically; a shell variable expanding to empty (--set \"$UNSET_VAR\").","commonSituations":"Empty shell variable expansion; a generated script emits --set args from a map and yields '' for a missing key; quoting accident that strips the value.","solutions":["Ensure every --set argument is non-empty and matches <module>.<key>=<value>.","When building --set args from variables, skip entries where the variable is unset or empty.","Quote arguments so the shell preserves them, and echo the assembled command if debugging a wrapper script."],"exampleFix":"# before\n#   --set \"$MY_VAR\"        # MY_VAR unset -> empty entry\n#\n# after\n#   --set \"bmm.project_knowledge=research\"","handlingStrategy":"validation","validationCode":"function isNonEmptySetEntry(entry) {\n  return typeof entry === 'string' && entry.length > 0 && entry.includes('=') && entry.includes('.');\n}\nconst entries = rawEntries.filter(isNonEmptySetEntry);\nconst overrides = parseSetEntries(entries);","typeGuard":"function isValidSetEntry(entry) {\n  return typeof entry === 'string' && /^\\S+\\.\\S+=/.test(entry);\n}","tryCatchPattern":"try {\n  overrides = parseSetEntries(entries);\n} catch (e) {\n  if (/--set: empty entry/.test(e.message)) {\n    // drop empty entries and retry, or warn the user\n    entries = entries.filter((e) => typeof e === 'string' && e.length > 0);\n    overrides = parseSetEntries(entries);\n  } else { throw e; }\n}","preventionTips":["Filter out empty/unset variables before passing --set args.","Validate --set entries against the <module>.<key>=<value> shape in your wrapper script before invoking the CLI."],"tags":["cli","set-overrides","argument-parsing"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}