{"record":{"id":"b6c786dfccc62e1d","repo":"coder/code-server","slug":"key-requires-a-value","errorCode":null,"errorMessage":"--${key} requires a value","messagePattern":"--(.+?) requires a value","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/node/cli.ts","lineNumber":448,"sourceCode":"      }\n\n      const option = options[key]\n      if (option.type === \"boolean\") {\n        ;(args[key] as boolean) = true\n        continue\n      }\n\n      // Might already have a value if it was the --long=value format.\n      if (typeof value === \"undefined\") {\n        // A value is only valid if it doesn't look like an option.\n        value = argv[i + 1] && !argv[i + 1].startsWith(\"-\") ? argv[++i] : undefined\n      }\n\n      if (!value && option.type === OptionalString) {\n        ;(args[key] as OptionalString) = new OptionalString(value)\n        continue\n      } else if (!value) {\n        throw error(`--${key} requires a value`)\n      }\n\n      if (key === \"idle-timeout-seconds\" && Number(value) <= 60) {\n        throw new Error(\"--idle-timeout-seconds must be greater than 60 seconds.\")\n      }\n\n      if (option.type === OptionalString && value === \"false\") {\n        continue\n      }\n\n      if (option.path) {\n        value = path.resolve(value)\n      }\n\n      switch (option.type) {\n        case \"string\":\n          ;(args[key] as string) = value\n          break","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/coder/code-server/blob/8a7bf87a4d66914e328d97815e2faa9f25097866/src/node/cli.ts#L430-L466","documentation":"code-server's CLI argument parser (parse, called from args) throws this when a non-boolean, non-OptionalString option is supplied without a value. A flag's value is taken from a `--flag=value` suffix or from the next argv token, but only if that token does not itself start with a dash. When neither yields a value, the parser cannot populate the option and aborts with `--<key> requires a value`.","triggerScenarios":"Passing a value-requiring flag with nothing after it (e.g. `code-server --bind-addr` as the last argument); passing a value that begins with a dash so it is mistaken for another option (e.g. `--cert-key -abc`); using a negative number directly after a flag like `--idle-timeout-seconds -5`, since argv[i+1].startsWith('-') makes the value undefined.","commonSituations":"Truncated or hand-edited shell scripts and systemd unit files where a variable holding the value expands to empty (e.g. `--bind-addr $ADDR` with ADDR unset); users copying boolean-style usage onto value options; typos where a later flag appears where the value was expected (e.g. forgetting the equals sign: `--bind-addr --port 8080`).","solutions":["Supply the missing value, either space-separated (`--bind-addr 0.0.0.0:8080`) or with equals (`--bind-addr=0.0.0.0:8080`).","If the value legitimately starts with a dash or is negative, use the `--flag=value` form, which bypasses the next-token dash check.","Quote variables in shell scripts (`--bind-addr \"$ADDR\"`) and verify the variable is non-empty (e.g. `${ADDR:?ADDR is not set}`) so an unset env var can't leave the flag valueless.","Run `code-server --help` to confirm the option actually takes a value; boolean options never need one."],"exampleFix":"// before (ADDR unset, value lost)\ncode-server --bind-addr $ADDR\n\n// after (fail fast or default)\ncode-server --bind-addr \"${ADDR:-0.0.0.0:8080}\"","handlingStrategy":"validation","validationCode":"function assertFlagHasValue(argv: string[], flag: string) {\n  const idx = argv.findIndex((a) => a === flag || a.startsWith(flag + \"=\"))\n  if (idx === -1) return true // flag not used\n  if (argv[idx].includes(\"=\")) return argv[idx].split(\"=\")[1] !== \"\"\n  return idx + 1 < argv.length && argv[idx + 1] !== \"\" && !argv[idx + 1].startsWith(\"-\")\n}\n// if (!assertFlagHasValue(process.argv, \"--bind-addr\")) { /* fix invocation */ }","typeGuard":"function hasFlagValue<T extends Record<string, unknown>>(args: T, key: keyof T): args is T & Record<keyof T, string> {\n  return typeof args[key] === \"string\" && (args[key] as string).length > 0\n}","tryCatchPattern":"try {\n  const args = await args(process.argv)\n  // use args\n} catch (err) {\n  if (err instanceof Error && err.message.endsWith(\"requires a value\")) {\n    const key = err.message.match(/^--(.+) requires a value$/)?.[1]\n    console.error(`The --${key} option needs a value. Try: --${key}=<value>. Use --help for details.`)\n    process.exit(1)\n  }\n  throw err\n}","preventionTips":["Always pass values for non-boolean flags, preferring the `--flag=value` form when the value may begin with a dash.","Quote shell variables holding CLI values and use ${VAR:?msg} to fail fast on unset variables.","Review startup scripts/systemd ExecStart lines after edits so flags don't end up trailing with no value.","Check `code-server --help` to confirm which options take values before adding them to an invocation."],"tags":["cli","argument-parsing","validation"],"backgroundTag":"missing-cli-argument","analyzedSha":"8a7bf87a4d66914e328d97815e2faa9f25097866","analyzedAt":"2026-09-22T02:34:03.345Z","contentChangedAt":"2026-09-22T02:34:03.345Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}