moeru-ai/airi · error · Error

The first `cap run` argument must be `ios` or `android`.

Error message

The first `cap run` argument must be `ios` or `android`.

What it means

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.

Solutions

  1. Pass the platform as the first element: capVitePlugin({ capArgs: ['ios', '--target', 'iPhone 16 Pro'] })
  2. Prefer deriving capArgs from parseCapViteCliArgs(argv) instead of assembling them by hand
  3. If driving the wrapper config via env, set CAP_VITE_CAP_ARGS_JSON as a JSON array starting with the platform

Example fix

// before
capVitePlugin({ capArgs: ['--target', 'emulator-5554'] }) // Error: The first `cap run` argument must be `ios` or `android`.

// after
capVitePlugin({ capArgs: ['android', '--target', 'emulator-5554'] })
Defensive patterns

Strategy: validation

Validate before calling

const platform = options.capArgs[0]
if (platform !== 'ios' && platform !== 'android')
  throw new Error(`capVitePlugin requires capArgs[0] to be ios|android, got: ${platform}`)
return capVitePlugin({ ...options })

Type guard

function isCapacitorPlatform(v: string | undefined): v is 'ios' | 'android' {
  return v === 'ios' || v === 'android'
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@0616eabd5b (2026-08-18). Data as JSON: /api/errors/72a2b9a166ca7bdf. Report an issue: GitHub.

Appendix: source

Thrown at packages/cap-vite/src/vite-plugin.ts:24

import process from 'node:process'

import { resolve } from 'node:path'

import * as readline from 'node:readline'

import { x } from 'tinyexec'

import { parseCapacitorPlatform, pickServerUrl, resolveCapRunArgs, shouldRestartForNativeChange } from './native'
import { errorMessageFromValue } from './utils/error-message'

export interface CapVitePluginOptions {
  capArgs: string[]
}

export function capVitePlugin(options: CapVitePluginOptions): Plugin {
  const platform = parseCapacitorPlatform(options.capArgs[0])
  if (!platform) {
    throw new Error('The first `cap run` argument must be `ios` or `android`.')
  }
  const resolvedPlatform: CapacitorPlatform = platform

  return {
    apply: 'serve',
    async configureServer(server) {
      const resolvedCapArgs = await resolveCapRunArgs(options.capArgs)
      const cwd = resolve(server.config.root)
      const platformRoot = resolve(cwd, resolvedPlatform)
      const debounceMs = 300
      const logger = server.config.logger

      let currentCapProcess: Result | undefined
      let restartTask: Promise<void> | undefined
      let queuedRestartReason: string | undefined
      let disposeShortcut: (() => void) | undefined
      let shuttingDown = false
      let restartTimer: NodeJS.Timeout | undefined

View on GitHub (pinned to 0616eabd5b)