moeru-ai/airi · error
CAP_VITE_CAP_ARGS_JSON must be a JSON string array.
Error message
CAP_VITE_CAP_ARGS_JSON must be a JSON string array.
What it means
Thrown by parseCapArgs() inside vite-wrapper-config.ts when process.env.CAP_VITE_CAP_ARGS_JSON is set but does not JSON.parse into an array of strings. It guards the env-var contract that runCapVite establishes when it spawns the wrapper Vite process.
Source
Thrown at packages/cap-vite/src/vite-wrapper-config.ts:15
import process from 'node:process'
import { defineConfig, loadConfigFromFile, mergeConfig } from 'vite'
import { capVitePlugin } from './vite-plugin'
function parseCapArgs(): string[] {
const value = process.env.CAP_VITE_CAP_ARGS_JSON
if (!value) {
return []
}
const parsed = JSON.parse(value)
if (!Array.isArray(parsed) || parsed.some(arg => typeof arg !== 'string')) {
throw new Error('CAP_VITE_CAP_ARGS_JSON must be a JSON string array.')
}
return parsed
}
function parseConfigLoader(): 'bundle' | 'native' | 'runner' | undefined {
const value = process.env.CAP_VITE_CONFIG_LOADER
if (value === 'bundle' || value === 'native' || value === 'runner') {
return value
}
return undefined
}
export default defineConfig(async (env) => {
const root = process.env.CAP_VITE_ROOT ?? process.cwd()
const baseConfigFile = process.env.CAP_VITE_BASE_CONFIG || undefined
const configLoader = parseConfigLoader()View on GitHub (pinned to 27111382b4)
Solutions
- Set CAP_VITE_CAP_ARGS_JSON to JSON.stringify(['ios']) style values only.
- Let runCapVite() own the env var; avoid setting it by hand.
- If scripting, validate with Array.isArray(parsed) && parsed.every(x => typeof x === 'string') before assigning the env.
Example fix
// before
process.env.CAP_VITE_CAP_ARGS_JSON = JSON.stringify({ platform: 'ios' })
// after
process.env.CAP_VITE_CAP_ARGS_JSON = JSON.stringify(['ios']) Defensive patterns
Strategy: validation
Validate before calling
function readCapArgsEnv(): string[] {
const raw = process.env.CAP_VITE_CAP_ARGS_JSON
if (!raw) return []
const parsed = JSON.parse(raw) as unknown
if (!Array.isArray(parsed) || parsed.some(a => typeof a !== 'string')) {
throw new Error('CAP_VITE_CAP_ARGS_JSON must be set to a JSON string array.')
}
return parsed
} Type guard
function isStringArray(value: unknown): value is string[] {
return Array.isArray(value) && value.every(v => typeof v === 'string')
} Try / catch
try {
parseCapArgs()
} catch (error) {
if (error instanceof Error && error.message.includes('JSON string array')) {
console.error('Fix CAP_VITE_CAP_ARGS_JSON; it must be a JSON-encoded string[].')
}
throw error
} Prevention
- Use JSON.stringify(['ios', ...]) when setting the env var manually.
- Let runCapVite own the env var; do not set it elsewhere.
- Add a CI assertion that the env var, when present, parses to a string[].
When it happens
Trigger: CAP_VITE_CAP_ARGS_JSON is set to a JSON object, a JSON scalar, a non-JSON string, or an array containing non-string elements (numbers, null). JSON.parse itself throwing (malformed JSON) propagates a SyntaxError before this guard; this guard specifically catches the shape mismatch.
Common situations: Manually exporting the env var with a wrong shape in a script; a build tool that stringifies an object instead of an array; copy-paste of a CLI arg string without JSON encoding; the env var surviving from an experiment that put objects in it.
Related errors
- The first `cap run` argument must be `ios` or `android`.
- Expected `cap run --list --json` to return a JSON array.
- AIRI host websocket bridge is unavailable
- cap-vite [vite args...] -- <ios|android> [cap run args...]
- The first `cap run` argument must be `ios` or `android`.
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/2ade96e160f2fb4a.
Report an issue: GitHub.