{"record":{"id":"2ade96e160f2fb4a","repo":"moeru-ai/airi","slug":"cap-vite-cap-args-json-must-be-a-json-string-array","errorCode":null,"errorMessage":"CAP_VITE_CAP_ARGS_JSON must be a JSON string array.","messagePattern":"CAP_VITE_CAP_ARGS_JSON must be a JSON string array\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cap-vite/src/vite-wrapper-config.ts","lineNumber":15,"sourceCode":"import process from 'node:process'\n\nimport { defineConfig, loadConfigFromFile, mergeConfig } from 'vite'\n\nimport { capVitePlugin } from './vite-plugin'\n\nfunction parseCapArgs(): string[] {\n  const value = process.env.CAP_VITE_CAP_ARGS_JSON\n  if (!value) {\n    return []\n  }\n\n  const parsed = JSON.parse(value)\n  if (!Array.isArray(parsed) || parsed.some(arg => typeof arg !== 'string')) {\n    throw new Error('CAP_VITE_CAP_ARGS_JSON must be a JSON string array.')\n  }\n\n  return parsed\n}\n\nfunction parseConfigLoader(): 'bundle' | 'native' | 'runner' | undefined {\n  const value = process.env.CAP_VITE_CONFIG_LOADER\n  if (value === 'bundle' || value === 'native' || value === 'runner') {\n    return value\n  }\n\n  return undefined\n}\n\nexport default defineConfig(async (env) => {\n  const root = process.env.CAP_VITE_ROOT ?? process.cwd()\n  const baseConfigFile = process.env.CAP_VITE_BASE_CONFIG || undefined\n  const configLoader = parseConfigLoader()","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/cap-vite/src/vite-wrapper-config.ts#L1-L33","documentation":"The generated wrapper config parses the CAP_VITE_CAP_ARGS_JSON environment variable, which runCapVite sets via JSON.stringify(capArgs). It throws when the variable is set but is not a JSON array whose elements are all strings — usually someone set it by hand or double-encoded it.","triggerScenarios":"Setting CAP_VITE_CAP_ARGS_JSON='ios --target x' (a plain string, not JSON), '[\"ios\", 1]' (non-string element), or a JSON.stringify-ed string that gets stringified again (double encoding). Running the wrapper vite config directly with a stale/incorrect env value.","commonSituations":"Manually invoking `vite --config <wrapper>` in CI and hand-writing the env var; env value carried over from a different tooling version; quoting layers in YAML/scripts mangling the JSON.","solutions":["Set it as a JSON string array: CAP_VITE_CAP_ARGS_JSON='[\"ios\",\"--target\",\"iPhone 16 Pro\"]'","Better: don't set it manually — invoke via `cap-vite -- ios ...` or runCapVite(), which serializes capArgs correctly","Unset the variable when running plain vite builds that don't go through the wrapper"],"exampleFix":"# before\nCAP_VITE_CAP_ARGS_JSON='ios --target \"iPhone 16 Pro\"' vite --config .cap-vite.config.ts\n\n# after\nCAP_VITE_CAP_ARGS_JSON='[\"ios\",\"--target\",\"iPhone 16 Pro\"]' vite --config .cap-vite.config.ts","handlingStrategy":"validation","validationCode":"// When setting the env yourself, always serialize an array of strings\nprocess.env.CAP_VITE_CAP_ARGS_JSON = JSON.stringify(['ios', '--target', 'iPhone 16 Pro'])","typeGuard":"function isStringArray(v: unknown): v is string[] {\n  return Array.isArray(v) && v.every(x => typeof x === 'string')\n}","tryCatchPattern":null,"preventionTips":["Prefer invoking via `cap-vite -- <platform>` or runCapVite() which sets the env correctly","Never hand-write the value as a plain argument string","Unset the variable for vite runs that bypass the wrapper"],"tags":["environment-variable","json","capacitor","vite"],"backgroundTag":"invalid-env-var","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}