{"record":{"id":"f83e62e6c000dd77","repo":"coder/code-server","slug":"invalid-config-config","errorCode":null,"errorMessage":"invalid config: ${config}","messagePattern":"invalid config: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/node/cli.ts","lineNumber":763,"sourceCode":"\n  const configFile = await fs.readFile(configPath, \"utf8\")\n  return parseConfigFile(configFile, configPath)\n}\n\n/**\n * parseConfigFile parses configFile into ConfigArgs.\n * configPath is used as the filename in error messages\n */\nexport function parseConfigFile(configFile: string, configPath: string): ConfigArgs {\n  if (!configFile) {\n    return { config: configPath }\n  }\n\n  const config = load(configFile, {\n    filename: configPath,\n  })\n  if (!config || typeof config === \"string\") {\n    throw new Error(`invalid config: ${config}`)\n  }\n\n  // We convert the config file into a set of flags.\n  // This is a temporary measure until we add a proper CLI library.\n  const configFileArgv = Object.entries(config)\n    .map(([optName, opt]) => {\n      if (opt === true) {\n        return `--${optName}`\n      } else if (Array.isArray(opt)) {\n        return opt.map((o) => `--${optName}=${o}`)\n      }\n      return `--${optName}=${opt}`\n    })\n    .flat()\n  const args = parse(configFileArgv, {\n    configFile: configPath,\n  })\n  return {","sourceCodeStart":745,"sourceCodeEnd":781,"githubUrl":"https://github.com/coder/code-server/blob/51f90a376b42e217b38937410fe2855e0c1db87e/src/node/cli.ts#L745-L781","documentation":"parseConfigFile (cli.ts:763) loads the YAML config and expects an object. If the loader returns a falsy value (empty file) or a bare string (e.g. a single scalar with no key:), the result is not a usable config object and the function throws `invalid config: <value>`. This guards the downstream Object.entries conversion of the config into flags.","triggerScenarios":"A config file that is empty, contains only a comment, or holds a single unkeyed scalar (e.g. just `hello` instead of `auth: password`). Also triggered by YAML that parses to a string via quoting quirks.","commonSituations":"Truncated config files from a bad deploy; hand-edited YAML where the top-level key was accidentally removed; templating that emitted an empty file on a missing variable.","solutions":["Ensure the config file contains at least one `key: value` pair, e.g. `auth: password`","Validate the YAML with `python -c 'import yaml,sys; print(yaml.safe_load(open(sys.argv[1])))' config.yaml` and confirm it is a dict","If the file is intentionally empty, delete it or set `config:` to a real path"],"exampleFix":"# before (config.yaml)\n# (empty or just a comment)\n\n# after (config.yaml)\nauth: password\nbind-addr: 127.0.0.1:8080","handlingStrategy":"try-catch","validationCode":"import yaml from \"js-yaml\"  // or the same loader code-server uses\nfunction validateConfigFile(path: string): void {\n  const loaded = yaml.load(fs.readFileSync(path, \"utf8\"))\n  if (!loaded || typeof loaded !== \"object\" || Array.isArray(loaded)) {\n    throw new Error(`invalid config: ${loaded}`)\n  }\n}","typeGuard":"function isConfigObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v)\n}","tryCatchPattern":"try {\n  const args = parseConfigFile(configFile, configPath)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"invalid config:\")) {\n    throw new Error(`Config file at ${configPath} did not parse to an object. Check YAML syntax.`)\n  }\n  throw e\n}","preventionTips":["Lint config.yaml in CI with a schema validator before deploy","Never template a config file that may resolve to empty (guard missing vars)","Keep a known-good config in version control to diff against"],"tags":["config","yaml","parsing","startup","configuration"],"backgroundTag":null,"analyzedSha":"51f90a376b42e217b38937410fe2855e0c1db87e","analyzedAt":"2026-08-12T11:27:34.273Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}