{"record":{"id":"51dae764cc0a99d7","repo":"coder/code-server","slug":"vscode-option-requires-a-flag-name-got-entry","errorCode":null,"errorMessage":"--vscode-option requires a flag name (got \"${entry}\")","messagePattern":"--vscode-option requires a flag name \\(got \"(.+?)\"\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/node/cli.ts","lineNumber":952,"sourceCode":"/**\n * Expand --vscode-option entries into VS Code server arguments.\n *\n * An entry is `flag=value`, or a bare `flag` meaning true.  A leading `--` on\n * the flag is optional, so both spellings people reach for work.  Repeating a\n * flag collects the values into an array, since several VS Code options take\n * one.\n *\n * `true` and `false` become booleans rather than strings.  VS Code tests these\n * flags for truthiness and the string \"false\" is truthy, so passing it along\n * verbatim would quietly do the opposite of what was asked.\n */\nexport const parseVscodeOptions = (entries: string[]): Record<string, string | boolean | string[]> => {\n  const parsed: Record<string, string | boolean | string[]> = {}\n\n  for (const entry of entries) {\n    const [flag, rawValue] = splitOnFirstEquals(entry.replace(/^--/, \"\"))\n    if (!flag) {\n      throw new Error(`--vscode-option requires a flag name (got \"${entry}\")`)\n    }\n\n    const value: string | boolean =\n      typeof rawValue === \"undefined\" || rawValue === \"true\" ? true : rawValue === \"false\" ? false : rawValue\n\n    const existing = parsed[flag]\n    if (typeof existing === \"undefined\") {\n      parsed[flag] = value\n    } else if (Array.isArray(existing)) {\n      existing.push(String(value))\n    } else {\n      parsed[flag] = [String(existing), String(value)]\n    }\n  }\n\n  return parsed\n}\n","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/coder/code-server/blob/88c2b7432e938f6918f21ff8d9dbfc641cd933d0/src/node/cli.ts#L934-L970","documentation":"Thrown by parseVscodeOptions in code-server's CLI (src/node/cli.ts) while expanding --vscode-option entries into VS Code server arguments. Each entry must be `flag=value` or a bare `flag`; a leading `--` is stripped and the remainder is split on the first `=`. The error fires when that leaves an empty flag name (an empty entry, an entry starting with `=`, or a bare `--`), which always indicates a typo or quoting bug, so code-server refuses to start rather than silently dropping the option.","triggerScenarios":"Running code-server with `--vscode-option \"\"` (empty quotes), `--vscode-option =value` (value with no flag name), or `--vscode-option --`; or setting the VSCODE_OPTIONS environment variable to a token that is empty or begins with `=` — env tokens are whitespace-split, appended to the vscode-option array (src/node/cli.ts:661-666), and run through the same parser. Any entry that is just `=` also triggers it.","commonSituations":"Shell variables expanding to empty (`--vscode-option \"$FLAG\"` with FLAG unset), a stray `=` pasted from docs or a value whose name got deleted, CI pipelines passing VSCODE_OPTIONS with malformed tokens, or scripts building the option array programmatically and including empty strings. The message echoes the offending entry verbatim, so the culprit is visible in the error output.","solutions":["Read the `(got \"...\")` part of the message: the entry is empty, starts with `=`, or is just `--`. Rewrite it as `name=value` or a bare flag name (e.g. `--vscode-option enable-sandbox`).","If the entry came from a shell variable, guard against empty expansion, e.g. `${MY_FLAG:+--vscode-option \"$MY_FLAG\"}`, so the flag is only passed when the variable is set.","If it came from VSCODE_OPTIONS, inspect the variable for stray `=`-leading or empty tokens and fix the spacing/quoting in the environment.","If you build the entries array in code, filter out empty or `=`-prefixed strings before the array reaches code-server."],"exampleFix":"# before — entry has no flag name\ncode-server --vscode-option =enable-sandbox\n\n# after — bare flag name\ncode-server --vscode-option enable-sandbox\n\n# before — variable may expand to an empty entry\ncode-server --vscode-option \"$MY_FLAG\"\n\n# after — pass the flag only when the variable is set\ncode-server ${MY_FLAG:+--vscode-option \"$MY_FLAG\"}","handlingStrategy":"validation","validationCode":"const hasFlagName = (entry: string): boolean => {\n  const flag = entry.replace(/^--/, \"\").split(\"=\")[0]\n  return flag.length > 0\n}\n\nconst invalid = entries.filter((e) => !hasFlagName(e))\nif (invalid.length > 0) {\n  throw new Error(`malformed --vscode-option entries (need name or name=value): ${invalid.join(\", \")}`)\n}\nconst parsed = parseVscodeOptions(entries.filter(hasFlagName))","typeGuard":"const isParsableVscodeOption = (entry: string): entry is string => {\n  const flag = entry.replace(/^--/, \"\").split(\"=\")[0]\n  return flag.length > 0\n}","tryCatchPattern":"try {\n  const vscodeOptions = parseVscodeOptions(entries)\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"--vscode-option requires a flag name\")) {\n    // Fail fast with the offending entry surfaced to the operator.\n    console.error(`Cannot start: ${err.message}`)\n    process.exit(1)\n  }\n  throw err\n}","preventionTips":["Always write entries as `name=value` or a bare `name`; never begin an entry with `=` or pass an empty string.","Quote shell variables and skip the whole flag when the variable is empty (`${VAR:+--vscode-option \"$VAR\"}`).","Lint VSCODE_OPTIONS tokens for empty or `=`-leading items before launching code-server in CI.","When building the vscode-option array programmatically, drop empty strings before handoff."],"tags":["code-server","cli","argument-validation","vscode-option","shell-quoting"],"backgroundTag":"invalid-cli-argument","analyzedSha":"88c2b7432e938f6918f21ff8d9dbfc641cd933d0","analyzedAt":"2026-08-21T18:11:29.142Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}