# eas submit iOS: типові помилки та як їх виправити

> eas submit падає? Справжні повідомлення EAS і App Store Connect, їхня причина й виправлення: ascAppId, ключ API, угода Apple, коди ITMS.

Оригінальна сторінка: [eas submit iOS: типові помилки та як їх виправити](https://devoria.fr/uk/blog/eas-submit-ios-errors-fix)
Автор: [Mehdi Azizi](https://devoria.fr/uk/mehdi-azizi)
Опубліковано: 2026-11-04
Останнє оновлення змісту: 2026-11-04


Коли `eas submit --platform ios` падає, повідомлення майже завжди підказує, куди дивитися. **Або твоя конфігурація EAS неповна, або блокує твій акаунт Apple, або Apple відхиляє бінарник.** Перші два випадки виправляються за кілька хвилин, без нового білда. Третій упізнаєш за кодом ITMS, і він майже завжди потребує нового білда.

Я публікую свої iOS-застосунки, серед них Solys, TradaZen і Nolera, через Expo та EAS. Повідомлення, наведені тут, скопійовані з вихідного коду EAS CLI в [офіційному репозиторії Expo на GitHub](https://github.com/expo/eas-cli), перевіреному 3 листопада 2026 року. Старий форум Expo тепер перенаправляє в Discord, тож код залишається найнадійнішим джерелом. Повний шлях, від файлу `eas.json` до відправки на перевірку, описано в статті [EAS Submit iOS: як опублікувати застосунок Expo в App Store](https://devoria.fr/uk/blog/eas-submit-ios-publish-expo-app-store). Прочитай її спершу. Тут ми лагодимо.

## Що робить eas submit і що йому потрібно

Згідно з [документацією Expo](https://docs.expo.dev/deploy/submit-to-app-stores/), команда надсилає твій файл `.ipa` в App Store Connect. Білд з'являється в TestFlight після обробки Apple, зазвичай за 10-15 хвилин. **Вона не відправляє твій застосунок на перевірку**: це ще треба зробити в App Store Connect.

[Сторінка Expo про відправку для iOS](https://docs.expo.dev/submit/ios/) називає три передумови:

- **платний акаунт Apple Developer**, обов'язковий для будь-якої відправки в App Store;
- **ідентифікатор бандла** в `ios.bundleIdentifier`;
- **встановлений EAS CLI**, підключений до твого акаунта Expo.

Для відправки без взаємодії та сама сторінка додає два налаштування:

- **`ascAppId`** у профілі `submit` файлу `eas.json`, тобто номер твоєї картки в App Store Connect;
- **ключ API App Store Connect**, яким керує EAS або який надаєш ти. Його створення, роль і відкликання детально описані в статті [ключ API App Store Connect (.p8)](https://devoria.fr/uk/blog/app-store-connect-api-key-p8).

Мінімальний профіль займає кілька рядків. Значення вигадане:

```json
{
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890"
      }
    }
  }
}
```

Якщо EAS уже зберігає твій ключ API, цього профілю достатньо. Так налаштовано більшість моїх застосунків.

## Читаємо повідомлення: три групи помилок

Перш ніж шукати виправлення, визнач момент, коли команда зупиняється. Ця таблиця: схема, яку я застосовую до кожного збою.

| Момент збою                            | Група              | Новий білд?  |
| -------------------------------------- | ------------------ | ------------ |
| До будь-якої відправки                 | Конфігурація EAS   | Ні           |
| Підключення до Apple, створення картки | Акаунт Apple       | Ні           |
| Після відправки, код ITMS-90xxx        | Бінарник відхилено | Майже завжди |

Подробиці видно на сторінці відправки в панелі Expo. [Expo радить](https://docs.expo.dev/deploy/submit-to-app-stores/) читати там журнали й шукати бульбашку «Build Annotations», яка вказує на поширені причини збою. У терміналі опція `--verbose` завжди показує журнали EAS Submit, згідно з [довідкою EAS CLI](https://docs.expo.dev/eas/cli/).

## Помилки конфігурації EAS

### «Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode.»

Ти запустив команду з `--non-interactive`, наприклад у CI, а твій профіль не містить `ascAppId`. [Код EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) тоді зупиняється: він не може ні поставити тобі запитання, ні створити картку замість тебе.

**Виправлення: скопіюй номер своєї картки в `ascAppId`.** [Expo пояснює, де його знайти](https://github.com/expo/fyi/blob/main/asc-app-id.md): в App Store Connect відкрий свій застосунок, потім App Information. Це поле Apple ID у розділі General Information, число приблизно з десяти цифр. Це не твоя електронна адреса Apple і не ідентифікатор бандла.

На Nolera без `ascAppId` команда вимагала сесію Apple Developer, яка спливає. Відколи номер є в `eas.json`, відправка більше нічого не питає.

> Додавай `ascAppId` до білда, а не після. До SDK 57 включно [відбиток, який обчислює Expo](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/src/sourcer/Expo.ts), завжди враховує `eas.json`. На Vigie, де версія середовища виконання йде за політикою `fingerprint`, додавання цього номера після білда змінило відбиток: оновлення, опубліковане потім, ніколи не дійшло б до встановленого білда. Починаючи з SDK 58 стандартний пресет відбитка, `balanced`, ігнорує `eas.json`, згідно з [журналом змін Expo](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/CHANGELOG.md).

### «App Store Connect API Keys cannot be set up in --non-interactive mode.»

Твій профіль не містить ключа, і в EAS немає жодного ключа, прив'язаного до твого застосунку. [Expo уточнює](https://docs.expo.dev/submit/ios/): у неінтерактивному режимі команда не може попросити в тебе ключ і падає з цим повідомленням.

Два можливі виправлення:

- **Дай EAS створити й зберігати ключ.** Запусти один раз `eas credentials --platform ios` в інтерактивному режимі на своїй машині й дай йому налаштувати ключ API App Store Connect для твого застосунку.
- **Принеси власний ключ** у `ascApiKeyPath`, `ascApiKeyIssuerId` і `ascApiKeyId`. Згідно з [довідкою eas.json](https://docs.expo.dev/eas/json/), ці три поля приймають змінні середовища, як-от `$ASC_API_KEY_PATH`.

На моєму останньому застосунку опція `--auto-submit` хотіла Apple ID, щоб створити свій ключ для відправки. Я вписав три поля свого власного ключа в профіль робочої копії, яку ніколи не комічу. Потім надіслав готовий білд з `--id` і `--non-interactive`.

### «EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.»

Змінна містить щось інше, ніж пароль застосунку, часто сам твій пароль Apple. [EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) перевіряє цей формат до будь-якої відправки.

Згідно з [довідкою Apple](https://support.apple.com/en-us/102654), пароль застосунку генерується на account.apple.com, у розділі App-Specific Passwords, з увімкненою двофакторною автентифікацією. Він відкликається, щойно ти змінюєш пароль свого акаунта Apple. **Expo вважає цей спосіб [менш безпечним, ніж ключ API](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md), який є його стандартним і рекомендованим способом.**

## Помилки акаунта Apple

### «… agree to the latest Program License Agreement in your developer account.»

Повне повідомлення починається з «You currently don't have access to this membership resource». З боку Apple сира відповідь може містити «Unable to process request - PLA Update available». Новіші кроки відправки EAS показують радше «A required Apple agreement is missing or has expired».

Причина та сама: Apple оновила угоду, і її ніхто не прийняв. **Приймати угоди може лише власник акаунта, Account Holder**, згідно з [таблицею ролей Apple](https://developer.apple.com/help/account/access/roles/). [Код EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) просить його зайти на сторінку Business в App Store Connect, а потім, якщо Apple це пропонує, у свій акаунт на developer.apple.com. Після цього перезапусти команду. Для угоди про платні застосунки є окремий гайд: [Paid Apps Agreement в App Store Connect](https://devoria.fr/uk/blog/paid-apps-agreement-statuses-w-8ben-first-payment).

### «App Store Connect rejected the API authentication credentials.»

Apple відповіла помилкою 401, `NOT_AUTHORIZED`. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) називає три причини: ключ більше не активний, ключ з іншого акаунта App Store Connect, або хибний Key ID, вміст ключа чи Issuer ID.

Перевір обидва ідентифікатори в App Store Connect, меню Users and Access, вкладка Integrations. Згідно з [Apple](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests), Issuer ID показано вгорі сторінки, а Key ID у списку активних ключів. **Відкликаний ключ ніколи не активується знову.** [Apple показує його](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys) 30 днів у розділі Revoked: треба згенерувати новий.

### «App Store Connect app for application identifier … was not found.»

Картку, на яку вказує `ascAppId`, неможливо знайти з твоїм ключем. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiUtils.ts) просить перевірити цей номер і те, що ключ справді має доступ до застосунку в потрібному акаунті. Він навіть перелічує кілька застосунків, видимих із цим ключем. В інструментах відправки Apple та сама проблема виглядає як «No suitable application records were found».

Повторюються три причини, дві з них описані в [цій гілці форумів Apple](https://developer.apple.com/forums/thread/106806):

- **Картки не існує.** Створи її в App Store Connect або прибери `ascAppId`, щоб команда створила її сама.
- **Номер з іншого акаунта.** Ти скопіював `ascAppId` іншої команди чи іншого проєкту.
- **Користувач не має доступу до застосунку.** App Manager або Developer може бути обмежений певними застосунками. А ключ команди [має доступ до всіх застосунків](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api) акаунта.

### «… is not available to team» або «… is not available to provider»

Це повідомлення з'являється, коли EAS створює картку замість тебе через відсутність `ascAppId`. Ідентифікатор бандла вже зайняла інша команда. [EAS просить](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/credentials/ios/appstore/ensureAppExists.ts) змінити його в конфігурації застосунку й перезапустити.

### «App name "…" is already taken. Using generated name "…"»

Це не збій. Коли назва вже зайнята в App Store, EAS додає шість випадкових символів і пробує знову, до п'яти разів. Перейменуєш картку пізніше в App Store Connect. Щоб цього уникнути, заповни `appName` і `language` у профілі до першої відправки: без `language` [основною мовою буде `en-US`](https://docs.expo.dev/eas/json/).

## Помилки бінарника: коди ITMS

Після відправки Apple обробляє білд. Якщо вона його відхиляє, журнал наводить один чи кілька кодів ITMS. Ось ті, які [крок відправки EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/functions/uploadToAsc.ts) розпізнає й пояснює:

| Код ITMS                   | Що відхиляє Apple                       | Виправлення            |
| -------------------------- | --------------------------------------- | ---------------------- |
| 90189                      | Номер білда вже зайнятий                | `autoIncrement`        |
| 90062, 90186, 90478        | Версія закрита або вже перевищена       | Підняти `version`      |
| 90683                      | Немає пояснення для дозволу             | `ios.infoPlist`        |
| 90725                      | Застарілий iOS SDK                      | Образ iOS або SDK Expo |
| 90054, 90055               | Бандл не збігається з карткою           | Виправити `ascAppId`   |
| 90022, 90023, 90391, 90713 | Іконки відсутні або неправильно описані | Переглянути іконки     |
| 90771                      | Немає ідентифікаторів фонових задач     | `ios.infoPlist`        |

Три уточнення з цих повідомлень:

- **Номер білда унікальний у межах версії.** Для 90189 EAS рекомендує `"autoIncrement": true` в `eas.json`. Усе описано в статті [номер білда і версія](https://devoria.fr/uk/blog/app-store-connect-build-number-version).
- **Для 90725** EAS радить вибрати новіший образ iOS в `eas.json`, а за потреби перейти на підтримуваний SDK Expo.
- **Для 90771** твій Info.plist оголошує фоновий режим `processing`, але не ключ `BGTaskSchedulerPermittedIdentifiers`.

Окрім 90054 і 90055, де достатньо вказати правильну картку або інший білд, **виправлення стосується бінарника: зроби новий білд і надішли його знову.** Для двох кодів є окремі гайди: [ITMS-90683 з Expo](https://devoria.fr/uk/blog/itms-90683-missing-purpose-string-expo) і [ITMS-90725](https://devoria.fr/uk/blog/itms-90725-sdk-version-issue-expo).

Наприкінці вересня 2026 року білд Solys відхилили під час доставки через ITMS-90683. Я прибрав пояснення для дозволу на фото, коли чистив файл конфігурації. Solys не використовує фото, але одна бібліотека проєкту викликає Photos API в iOS. **Apple аналізує бінарник, а не реальне використання:** відтоді я ніколи не прибираю ці пояснення.

Статус Missing Compliance натомість не є помилкою відправки. Бракує твоєї декларації про шифрування, яку пояснено в [гайді з публікації через EAS](https://devoria.fr/uk/blog/eas-submit-ios-publish-expo-app-store).

## Мій чекліст перед кожною відправкою

- `ascAppId` є в профілі `submit`, доданий до білда.
- Ключем API керує EAS, або його три поля вказують на `.p8`, що лежить поза репозиторієм.
- Account Holder прийняв останні угоди в App Store Connect.
- `autoIncrement` увімкнено разом із `"appVersionSource": "remote"`, що [рекомендує Expo](https://docs.expo.dev/build-reference/app-versions/) починаючи з EAS CLI 12.
- `version` вища за останню схвалену версію.
- Кожен чутливий API, присутній у бінарнику, має своє пояснення для дозволу.
- Для нового застосунку `appName` і `language` заповнені до першої відправки.

## Відправ свій перший застосунок і не застрягни

Команда лише один крок. [iOS & Android Kit](https://devoria.fr/uk/kits/ios) спирається на стартовий код моїх застосунків, разом із підписками, і веде через чотири етапи до App Store у твоєму темпі.

Якщо готуєш свій перший реліз, [пройди безкоштовну діагностику](https://devoria.fr/uk/diagnostic): вона покаже, що тебе насправді блокує, і надішле мій чекліст проти відмов Apple. Про картку, скриншоти й перевірку крок за кроком розповідає сторінка [опублікувати застосунок в App Store](https://devoria.fr/uk/expertise/publish-an-app-on-the-app-store).

## Поширені запитання

### Чому eas submit падає лише в CI?

У режимі `--non-interactive` команда нічого не може в тебе запитати. Їй потрібен `ascAppId` у профілі й ключ API, уже прив'язаний до застосунку, або три його поля в `eas.json`. На твоїй машині вона б поставила ці запитання.

### Чи треба робити новий білд після помилки eas submit?

Лише якщо Apple відхиляє бінарник із кодом ITMS. Виняток: для ITMS-90054 і 90055 білд був спрямований не на ту картку, достатньо надіслати його на правильну. Помилки конфігурації й акаунта виправляються в `eas.json`, в App Store Connect або у твоєму акаунті Apple. Потім ти надсилаєш той самий білд, наприклад з `--latest` або `--id`.

### Де подивитися журнали відправки EAS Submit?

На сторінці відправки в панелі Expo. Expo радить читати там журнали й бульбашку «Build Annotations». У терміналі додай `--verbose`, щоб журнали показувалися завжди.

### Чи можна використовувати eas submit з безкоштовним акаунтом Apple?

Ні. Expo вимагає платний акаунт Apple Developer, щоб надіслати застосунок в App Store. Безкоштовний акаунт дозволяє тестувати на власному iPhone, але не користуватися App Store Connect.

### Яку роль дати ключу API для eas submit?

Гайд Expo дає ключу роль Admin. Згідно з таблицею ролей Apple, надсилати білди можуть також ролі App Manager і Developer. Мої білди Expo працюють із ключем команди з роллю App Manager. Генерувати ключ команди можуть лише Account Holder і Admins.

### Що означає «Increment Build Number» в EAS?

Apple відхилила білд із кодом ITMS-90189: такий номер білда вже існує для цієї версії. Увімкни `"autoIncrement": true` в `eas.json` або підніми `ios.buildNumber`, а потім зроби новий білд.


## Твій проєкт

[Review Kit](https://devoria.fr/uk/kits/app-review): Мій чекліст для перевірки в App Store, виправлені відмови Apple, чекліст для Google Play і три скіли для Claude Code. 2 499 ₴.

[iOS & Android Kit](https://devoria.fr/uk/kits/ios): Створи свій застосунок для iPhone і Android з Claude Code: стартовий код моїх застосунків, шлях до публікації в сторах і всі кіти. 4 999 ₴.

[Діагностика: що відділяє тебе від твого застосунку для iPhone](https://devoria.fr/uk/diagnostic): 7 запитань, 60 секунд: ти дізнаєшся, що насправді заважає тобі опублікувати застосунок для iPhone, отримаєш свій шлях у 4 кроки і кіт, який тобі підходить.
