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

runCapVite, the programmatic entry, validates capArgs[0] with parseCapacitorPlatform before doing anything: only 'ios' or 'android' may be the first `cap run` argument. This mirrors the CLI check and fails fast before spawning Vite.

Solutions

  1. Prepend the platform: runCapVite([], ['android', '--target', 'emulator-5554'])
  2. Validate with the same rule before calling: capArgs[0] === 'ios' || capArgs[0] === 'android'
  3. For raw CLI input, run it through parseCapViteCliArgs first, which produces correctly ordered capArgs

Example fix

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

// after
await runCapVite([], ['android', '--target', 'emulator-5554'])
Defensive patterns

Strategy: validation

Validate before calling

const platform = capArgs[0]
if (platform !== 'ios' && platform !== 'android')
  throw new Error(`capArgs must start with ios|android, got: ${platform}`)
await runCapVite(viteArgs, capArgs)

Type guard

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

Prevention

When it happens

Trigger: Calling runCapVite(viteArgs, []) with an empty capArgs array, or with a flag first: runCapVite([], ['--target', 'emulator-5554']) — capArgs[0] is not a platform.

Common situations: Wrapping runCapVite in tooling that forwards user flags verbatim and forgets to prepend the platform; empty array from a defaulted parameter.

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@677329427f (2026-08-18). Data as JSON: /api/errors/bfe972d9760ee46c. Report an issue: GitHub.

Appendix: source

Thrown at packages/cap-vite/src/index.ts:157

    index += parsedArg.consumedArgs
  }

  return {
    baseConfigFile,
    configLoader,
    projectRoot,
    viteArgs: forwardedViteArgs,
    wrapperConfigFile: resolveWrapperConfigFile(),
  }
}

export async function runCapVite(
  viteArgs: string[],
  capArgs: string[],
  options: RunCapViteOptions = {},
): Promise<Output> {
  if (!parseCapacitorPlatform(capArgs[0])) {
    throw new Error('The first `cap run` argument must be `ios` or `android`.')
  }

  const cwd = resolve(options.cwd ?? process.cwd())
  const prepared = prepareCapViteLaunch(viteArgs, cwd)

  return await x('vite', ['--config', prepared.wrapperConfigFile, ...prepared.viteArgs], {
    throwOnError: false,
    nodeOptions: {
      cwd,
      env: {
        CAP_VITE_BASE_CONFIG: prepared.baseConfigFile ?? '',
        CAP_VITE_CAP_ARGS_JSON: JSON.stringify(capArgs),
        CAP_VITE_CONFIG_LOADER: prepared.configLoader ?? '',
        CAP_VITE_ROOT: prepared.projectRoot,
      },
      stdio: 'inherit',
    },
  })

View on GitHub (pinned to 677329427f)