{"record":{"id":"3e27daa236767d42","repo":"expo/expo","slug":"bad-args","errorCode":"BAD_ARGS","errorMessage":"Platform \"${platform}\" is not configured to use the Metro bundler in the project Expo config, or is missing from the supported platforms in the platforms array: [${configPlatforms.join(', ')}].","messagePattern":"Platform \"(.+?)\" is not configured to use the Metro bundler in the project Expo config, or is missing from the supported platforms in the platforms array: \\[(.+?)\\]\\.","errorType":"exception","errorClass":"CommandError","httpStatus":null,"severity":"error","filePath":"packages/@expo/cli/src/export/resolveOptions.ts","lineNumber":47,"sourceCode":"  const platformsAvailable: Partial<PlatformBundlers> = Object.fromEntries(\n    Object.entries(platformBundlers).filter(\n      ([platform, bundler]) => bundler === 'metro' && configPlatforms.includes(platform as Platform)\n    )\n  );\n\n  if (!Object.keys(platformsAvailable).length) {\n    throw new CommandError(\n      `No platforms are configured to use the Metro bundler in the project Expo config.`\n    );\n  }\n\n  const assertPlatformBundler = (platform: Platform): Platform => {\n    if (!platformsAvailable[platform]) {\n      if (!configPlatforms.includes(platform) && platform === 'web') {\n        // Pass through so the more robust error message is shown.\n        return platform;\n      }\n      throw new CommandError(\n        'BAD_ARGS',\n        `Platform \"${platform}\" is not configured to use the Metro bundler in the project Expo config, or is missing from the supported platforms in the platforms array: [${configPlatforms.join(\n          ', '\n        )}].`\n      );\n    }\n\n    return platform;\n  };\n\n  const knownPlatforms = ['android', 'ios', 'web', 'tvos', 'macos'] as Platform[];\n  const assertPlatformIsKnown = (platform: string): Platform => {\n    if (!knownPlatforms.includes(platform as Platform)) {\n      throw new CommandError(\n        `Unsupported platform \"${platform}\". Options are: ${knownPlatforms.join(',')},all`\n      );\n    }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/expo/expo/blob/b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee/packages/@expo/cli/src/export/resolveOptions.ts#L29-L65","documentation":"Thrown by assertPlatformBundler when the requested platform is not present in platformsAvailable (the platforms wired to the Metro bundler in the project's Expo config). It fires after the early 'no platforms' guard and the special web pass-through, so it specifically rejects a platform that is known but not enabled for Metro. The message also lists configPlatforms so the developer can see which platforms the project actually declares.","triggerScenarios":"Calling an export/resolveOptions flow with a platform (e.g. 'ios' or 'tvos') that is absent from platformsAvailable, when the platform is not 'web' (web is passed through to a more robust error). platformsAvailable is built from getPlatformBundlers/config and the platform must be both in configPlatforms and assigned the Metro bundler.","commonSituations":"Running `expo export -p ios` in a project whose app.json omits 'ios' from the platforms array, or whose platform bundler is set to something other than metro. Configuring platforms: ['android','web'] and then requesting ios. Migrating a config and forgetting to re-enable a platform.","solutions":["Add the missing platform to the `platforms` array in app.json/app.config.js (e.g. platforms: [\"android\",\"ios\",\"web\"]).","Verify the platform's bundler is set to 'metro' in the Expo config (getPlatformBundlers); for non-web platforms metro is the default unless overridden.","Run with a platform that is already enabled, or use `-p all` to export every platform present in platformsAvailable.","If exporting web specifically, use `expo export -p web` or the dedicated web export path rather than requesting web through the metro-only flow."],"exampleFix":"// before: app.json\n{ \"expo\": { \"platforms\": [\"android\"] } }\n// after\n{ \"expo\": { \"platforms\": [\"android\", \"ios\"] } }","handlingStrategy":"validation","validationCode":"// Before calling export/resolveOptions with a platform, ensure it is enabled for metro.\nimport { getConfig } from '@expo/config';\nconst { exp } = getConfig(projectRoot);\nconst configPlatforms = exp.platforms ?? [];\nconst platformBundlers = exp.platformBundlers ?? {}; // or use getPlatformBundlers\nconst isAvailable = configPlatforms.includes(platform) && platformBundlers[platform] === 'metro';\nif (!isAvailable) {\n  throw new Error(`Enable ${platform} in app config platforms and assign it the metro bundler.`);\n}","typeGuard":"function isMetroPlatform(platform: string, configPlatforms: string[], platformBundlers: Record<string, string>): boolean {\n  return configPlatforms.includes(platform) && platformBundlers[platform] === 'metro';\n}","tryCatchPattern":"try {\n  await resolveOptions({ platform });\n} catch (e) {\n  if (e instanceof CommandError && e.code === 'BAD_ARGS' && /not configured to use the Metro bundler/.test(e.message)) {\n    // prompt user to enable the platform in app config\n  } else throw e;\n}","preventionTips":["Keep app config `platforms` in sync with the bundlers you actually target.","Validate the requested platform against config before scripting exports.","Use `-p all` to operate on every configured platform instead of guessing."],"tags":["expo-cli","config","platforms","metro","bad-args"],"backgroundTag":null,"analyzedSha":"b09195aac27c9e4a63daaf12dcb6f00b6b2e08ee","analyzedAt":"2026-08-12T15:59:58.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}