{"record":{"id":"72a2b9a166ca7bdf","repo":"moeru-ai/airi","slug":"the-first-cap-run-argument-must-be-ios-or-and-72a2b9","errorCode":null,"errorMessage":"The first `cap run` argument must be `ios` or `android`.","messagePattern":"The first `cap run` argument must be `ios` or `android`\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cap-vite/src/vite-plugin.ts","lineNumber":24,"sourceCode":"import process from 'node:process'\n\nimport { resolve } from 'node:path'\n\nimport * as readline from 'node:readline'\n\nimport { x } from 'tinyexec'\n\nimport { parseCapacitorPlatform, pickServerUrl, resolveCapRunArgs, shouldRestartForNativeChange } from './native'\nimport { errorMessageFromValue } from './utils/error-message'\n\nexport interface CapVitePluginOptions {\n  capArgs: string[]\n}\n\nexport function capVitePlugin(options: CapVitePluginOptions): Plugin {\n  const platform = parseCapacitorPlatform(options.capArgs[0])\n  if (!platform) {\n    throw new Error('The first `cap run` argument must be `ios` or `android`.')\n  }\n  const resolvedPlatform: CapacitorPlatform = platform\n\n  return {\n    apply: 'serve',\n    async configureServer(server) {\n      const resolvedCapArgs = await resolveCapRunArgs(options.capArgs)\n      const cwd = resolve(server.config.root)\n      const platformRoot = resolve(cwd, resolvedPlatform)\n      const debounceMs = 300\n      const logger = server.config.logger\n\n      let currentCapProcess: Result | undefined\n      let restartTask: Promise<void> | undefined\n      let queuedRestartReason: string | undefined\n      let disposeShortcut: (() => void) | undefined\n      let shuttingDown = false\n      let restartTimer: NodeJS.Timeout | undefined","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/moeru-ai/airi/blob/0616eabd5ba89c7bcef0eb1da84694b9c285c573/packages/cap-vite/src/vite-plugin.ts#L6-L42","documentation":"The cap-vite Vite plugin validates options.capArgs[0] at construction time with parseCapacitorPlatform and throws when it is not 'ios' or 'android'. Normally capArgs arrive already validated from the CLI/env pipeline (CAP_VITE_CAP_ARGS_JSON), so hitting this means the plugin was instantiated directly with malformed args.","triggerScenarios":"Calling capVitePlugin({ capArgs: [] }) (empty array), capVitePlugin({ capArgs: ['--target', 'x'] }) (flag first), or passing a platform string with wrong case; the plugin factory throws before Vite even starts.","commonSituations":"Using capVitePlugin in a custom vite.config.ts instead of going through `cap-vite -- <platform>`; hand-building capArgs from user input without putting the platform first; tests constructing the plugin with placeholder args.","solutions":["Pass the platform as the first element: capVitePlugin({ capArgs: ['ios', '--target', 'iPhone 16 Pro'] })","Prefer deriving capArgs from parseCapViteCliArgs(argv) instead of assembling them by hand","If driving the wrapper config via env, set CAP_VITE_CAP_ARGS_JSON as a JSON array starting with the platform"],"exampleFix":"// before\ncapVitePlugin({ capArgs: ['--target', 'emulator-5554'] }) // Error: The first `cap run` argument must be `ios` or `android`.\n\n// after\ncapVitePlugin({ capArgs: ['android', '--target', 'emulator-5554'] })","handlingStrategy":"validation","validationCode":"const platform = options.capArgs[0]\nif (platform !== 'ios' && platform !== 'android')\n  throw new Error(`capVitePlugin requires capArgs[0] to be ios|android, got: ${platform}`)\nreturn capVitePlugin({ ...options })","typeGuard":"function isCapacitorPlatform(v: string | undefined): v is 'ios' | 'android' {\n  return v === 'ios' || v === 'android'\n}","tryCatchPattern":null,"preventionTips":["Derive capArgs from parseCapViteCliArgs instead of constructing them ad hoc","Prefer running through the cap-vite CLI so validation happens upstream","Cover plugin construction with a unit test asserting the platform precondition"],"tags":["capacitor","vite","plugin","arguments"],"backgroundTag":"invalid-cli-argument","analyzedSha":"0616eabd5ba89c7bcef0eb1da84694b9c285c573","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}