# Erori eas submit iOS: cauze și cum le rezolvi

> eas submit eșuează? Mesajele reale din EAS și App Store Connect, cauza și rezolvarea lor: ascAppId, cheie API, contract Apple, coduri ITMS.

Pagina originală: [Erori eas submit iOS: cauze și cum le rezolvi](https://devoria.fr/ro/blog/erori-eas-submit-ios-rezolvare)
Autor: [Mehdi Azizi](https://devoria.fr/ro/mehdi-azizi)
Publicare: 2026-11-04
Ultima revizuire a conținutului: 2026-11-04


Când `eas submit --platform ios` eșuează, mesajul îți spune aproape mereu unde să te uiți. **Ori configurația EAS e incompletă, ori contul tău Apple blochează, ori Apple refuză binarul.** Primele două cazuri se rezolvă în câteva minute, fără build nou. Al treilea se recunoaște după un cod ITMS și cere aproape mereu un build nou.

Îmi public aplicațiile iOS, printre care Solys, TradaZen și Nolera, cu Expo și EAS. Mesajele citate aici sunt copiate din codul sursă al EAS CLI, de pe [repository-ul GitHub oficial al Expo](https://github.com/expo/eas-cli), recitit pe 3 noiembrie 2026. Vechiul forum Expo trimite acum spre Discord: codul rămâne sursa cea mai sigură. Pentru tot parcursul, de la fișierul `eas.json` până la trimiterea la review, citește întâi [EAS Submit iOS: publică o aplicație Expo în App Store](https://devoria.fr/ro/blog/eas-submit-ios-publicare-aplicatie-expo-app-store). Aici reparăm.

## Ce face eas submit și de ce are nevoie

Conform [documentației Expo](https://docs.expo.dev/deploy/submit-to-app-stores/), comanda trimite fișierul tău `.ipa` în App Store Connect. Build-ul apare în TestFlight după procesarea de către Apple, de obicei în 10-15 minute. **Comanda nu trimite aplicația la review**: pasul ăsta îl faci tu în App Store Connect.

[Pagina Expo despre trimiterea pe iOS](https://docs.expo.dev/submit/ios/) enumeră trei condiții:

- **un cont Apple Developer plătit**, obligatoriu pentru orice trimitere în App Store;
- **identificatorul de bundle** în `ios.bundleIdentifier`;
- **EAS CLI instalat** și conectat la contul tău Expo.

Pentru trimitere fără interacțiune, aceeași pagină adaugă două setări:

- **`ascAppId`** în profilul `submit` din `eas.json`, numărul fișei tale din App Store Connect;
- **o cheie API App Store Connect**, gestionată de EAS sau furnizată de tine. Crearea, rolul și revocarea ei sunt explicate în [cheia API App Store Connect (.p8)](https://devoria.fr/ro/blog/cheie-api-app-store-connect-p8).

Profilul minim încape în câteva rânduri. Valoarea e fictivă:

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

Dacă EAS îți păstrează deja cheia API, profilul ăsta e suficient. Așa e la majoritatea aplicațiilor mele.

## Cum citești mesajul: trei familii de erori

Înainte să cauți soluția, vezi în ce moment se oprește comanda. Tabelul ăsta e grila pe care o aplic la fiecare eșec.

| Momentul eșecului                  | Familie          | Build nou?    |
| ---------------------------------- | ---------------- | ------------- |
| Înainte de orice trimitere         | Configurație EAS | Nu            |
| Conectarea la Apple, crearea fișei | Cont Apple       | Nu            |
| După trimitere, cod ITMS-90xxx     | Binar refuzat    | Aproape mereu |

Detaliile se văd pe pagina trimiterii, în dashboard-ul Expo. [Expo recomandă](https://docs.expo.dev/deploy/submit-to-app-stores/) să citești acolo logurile și să cauți bula „Build Annotations”, care semnalează cauzele frecvente de eșec. În terminal, opțiunea `--verbose` afișează mereu logurile EAS Submit, conform [referinței EAS CLI](https://docs.expo.dev/eas/cli/).

## Erorile de configurație EAS

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

Ai rulat comanda cu `--non-interactive`, de exemplu în CI, iar profilul tău nu conține `ascAppId`. [Codul EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) se oprește atunci: nu te poate întreba nimic și nici nu poate crea fișa în locul tău.

**Soluția: copiază numărul fișei tale în `ascAppId`.** [Expo îți arată unde îl găsești](https://github.com/expo/fyi/blob/main/asc-app-id.md): în App Store Connect, deschide aplicația, apoi App Information. E câmpul Apple ID, sub General Information, un număr de vreo zece cifre. Nu e nici adresa ta de e-mail Apple, nici identificatorul de bundle.

La Nolera, fără `ascAppId`, comanda îmi cerea o sesiune Apple Developer, care expiră. De când numărul e în `eas.json`, trimiterea nu mai cere nimic.

> Adaugă `ascAppId` înainte de build, nu după. Până la SDK 57, [amprenta calculată de Expo](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/src/sourcer/Expo.ts) include mereu `eas.json`. La Vigie, a cărei versiune de runtime urmează politica `fingerprint`, adăugarea acestui număr după un build a schimbat amprenta: un update publicat ulterior n-ar fi ajuns niciodată la build-ul instalat. De la SDK 58, presetul implicit al amprentei, `balanced`, ignoră `eas.json`, conform [changelog-ului 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.”

Profilul tău nu conține nicio cheie, iar EAS nu are nicio cheie atașată aplicației. [Expo precizează](https://docs.expo.dev/submit/ios/): în modul neinteractiv, comanda nu-ți poate cere o cheie și eșuează cu acest mesaj.

Două soluții posibile:

- **Lasă EAS să creeze și să păstreze cheia.** Rulează o dată `eas credentials --platform ios` în mod interactiv, pe calculatorul tău, și lasă-l să configureze o cheie API App Store Connect pentru aplicația ta.
- **Adu propria cheie** în `ascApiKeyPath`, `ascApiKeyIssuerId` și `ascApiKeyId`. Conform [referinței eas.json](https://docs.expo.dev/eas/json/), aceste trei câmpuri acceptă variabile de mediu, ca `$ASC_API_KEY_PATH`.

La ultima mea aplicație, opțiunea `--auto-submit` voia un Apple ID ca să-și creeze cheia de trimitere. Am pus cele trei câmpuri ale propriei chei în profilul din copia mea de lucru, niciodată commit-uită. Apoi am trimis build-ul terminat cu `--id` și `--non-interactive`.

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

Variabila conține altceva decât o parolă de aplicație, adesea chiar parola ta Apple. [EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) verifică formatul ăsta înainte de orice trimitere.

Conform [ajutorului Apple](https://support.apple.com/en-us/102654), o parolă de aplicație se generează pe account.apple.com, secțiunea App-Specific Passwords, cu autentificarea în doi pași activată. E revocată imediat ce schimbi parola contului Apple. **Expo consideră această metodă [mai puțin sigură decât cheia API](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md), metoda sa implicită și recomandată.**

## Erorile contului Apple

### „… agree to the latest Program License Agreement in your developer account.”

Mesajul complet începe cu „You currently don't have access to this membership resource”. De partea Apple, răspunsul brut poate conține „Unable to process request - PLA Update available”. Pașii de trimitere mai noi din EAS afișează mai degrabă „A required Apple agreement is missing or has expired”.

Cauza e aceeași: Apple a actualizat un contract și nimeni nu l-a acceptat. **Doar titularul contului, Account Holder, poate accepta contractele**, conform [tabelului de roluri Apple](https://developer.apple.com/help/account/access/roles/). [Codul EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) îi cere să treacă prin pagina Business din App Store Connect, apoi, dacă Apple îi propune, prin contul său de pe developer.apple.com. Rulează apoi din nou comanda. Contractul pentru aplicațiile plătite are ghidul lui: [Paid Apps Agreement în App Store Connect](https://devoria.fr/ro/blog/paid-apps-agreement-statusuri-w-8ben-prima-plata).

### „App Store Connect rejected the API authentication credentials.”

Apple a răspuns cu o eroare 401, `NOT_AUTHORIZED`. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) dă trei cauze: o cheie care nu mai e activă, o cheie din alt cont App Store Connect, sau un Key ID, un conținut de cheie ori un Issuer ID greșit.

Verifică cei doi identificatori în App Store Connect, meniul Users and Access, tabul Integrations. Conform [Apple](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests), Issuer ID apare în partea de sus a paginii, iar Key ID în lista cheilor active. **O cheie revocată nu se mai reactivează niciodată.** [Apple o afișează](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys) 30 de zile sub Revoked: trebuie să generezi una nouă.

### „App Store Connect app for application identifier … was not found.”

Fișa indicată de `ascAppId` nu poate fi găsită cu cheia ta. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiUtils.ts) îți cere să verifici numărul și dacă cheia are într-adevăr acces la aplicație în contul corect. Îți listează chiar câteva aplicații vizibile cu cheia asta. Cu uneltele de trimitere Apple, aceeași problemă apare sub forma „No suitable application records were found”.

Trei cauze apar des, două dintre ele semnalate în [acest thread de pe forumurile Apple](https://developer.apple.com/forums/thread/106806):

- **Fișa nu există.** Creeaz-o în App Store Connect sau scoate `ascAppId` ca s-o creeze comanda.
- **Numărul vine din alt cont.** Ai copiat `ascAppId` de la altă echipă sau din alt proiect.
- **Utilizatorul n-are acces la aplicație.** Un App Manager sau un Developer poate fi limitat la anumite aplicații. O cheie de echipă, în schimb, [are acces la toate aplicațiile](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api) din cont.

### „… is not available to team” sau „… is not available to provider”

Mesajul apare când EAS creează fișa în locul tău, în lipsa `ascAppId`. Identificatorul de bundle e deja luat de altă echipă. [EAS îți cere](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/credentials/ios/appstore/ensureAppExists.ts) să-l schimbi în configurația aplicației, apoi să rulezi din nou.

### „App name "…" is already taken. Using generated name "…"”

Nu e un eșec. Când numele e deja luat în App Store, EAS adaugă șase caractere aleatorii și încearcă din nou, de până la cinci ori. Redenumești fișa mai târziu în App Store Connect. Ca să eviți asta, completează `appName` și `language` în profil înainte de prima trimitere: fără `language`, [limba principală e `en-US`](https://docs.expo.dev/eas/json/).

## Erorile binarului: codurile ITMS

După trimitere, Apple procesează build-ul. Dacă îl refuză, logul citează unul sau mai multe coduri ITMS. Iată-le pe cele pe care [pasul de trimitere din EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/functions/uploadToAsc.ts) le recunoaște și le traduce:

| Cod ITMS                   | Ce refuză Apple                              | Soluție                  |
| -------------------------- | -------------------------------------------- | ------------------------ |
| 90189                      | Număr de build deja folosit                  | `autoIncrement`          |
| 90062, 90186, 90478        | Versiune închisă sau deja depășită           | Crește `version`         |
| 90683                      | Lipsește textul de permisiune                | `ios.infoPlist`          |
| 90725                      | SDK iOS prea vechi                           | Imagine iOS sau SDK Expo |
| 90054, 90055               | Bundle diferit de fișa vizată                | Corectează `ascAppId`    |
| 90022, 90023, 90391, 90713 | Iconițe lipsă sau declarate greșit           | Revizuiește iconițele    |
| 90771                      | Lipsesc identificatorii sarcinilor de fundal | `ios.infoPlist`          |

Trei precizări din aceste mesaje:

- **Numărul de build e unic pentru fiecare versiune.** Pentru 90189, EAS recomandă `"autoIncrement": true` în `eas.json`. Totul e în [numărul de build și versiunea](https://devoria.fr/ro/blog/build-number-app-store-connect-versiune).
- **Pentru 90725**, EAS îți recomandă să alegi o imagine iOS mai nouă în `eas.json` și, dacă e nevoie, să treci la un SDK Expo suportat.
- **Pentru 90771**, Info.plist-ul tău declară modul de fundal `processing`, dar nu și cheia `BGTaskSchedulerPermittedIdentifiers`.

În afară de 90054 și 90055, unde ajunge să ținești fișa corectă sau alt build, **soluția atinge binarul: fă un build nou, apoi trimite-l din nou.** Două coduri au ghidul lor: [ITMS-90683 cu Expo](https://devoria.fr/ro/blog/itms-90683-missing-purpose-string-expo) și [ITMS-90725](https://devoria.fr/ro/blog/itms-90725-sdk-version-issue-expo).

La sfârșitul lui septembrie 2026, un build Solys a fost refuzat la livrare pentru ITMS-90683. Scosesem un text de permisiune pentru poze în timp ce făceam curat în fișierul de configurație. Solys nu folosește pozele, dar o bibliotecă din proiect apelează API-ul Photos din iOS. **Apple analizează binarul, nu utilizarea reală:** de atunci nu mai scot niciodată textele astea.

Statusul Missing Compliance, în schimb, nu e o eroare de trimitere. Lipsește declarația ta despre criptare, explicată în [ghidul de publicare cu EAS](https://devoria.fr/ro/blog/eas-submit-ios-publicare-aplicatie-expo-app-store).

## Checklist-ul meu înainte de fiecare trimitere

- `ascAppId` e în profilul `submit`, adăugat înainte de build.
- Cheia API e gestionată de EAS, sau cele trei câmpuri ale ei indică un `.p8` ținut în afara repository-ului.
- Account Holder a acceptat ultimele contracte în App Store Connect.
- `autoIncrement` e activ, cu `"appVersionSource": "remote"`, [recomandat de Expo](https://docs.expo.dev/build-reference/app-versions/) de la EAS CLI 12.
- `version` e mai mare decât ultima versiune aprobată.
- Fiecare API sensibil prezent în binar are textul lui de permisiune.
- Pentru o aplicație nouă, `appName` și `language` sunt completate înainte de prima trimitere.

## Trimite-ți prima aplicație fără să te blochezi

Comanda e doar un pas. [iOS & Android Kit](https://devoria.fr/ro/kits/ios) pornește de la codul de start al aplicațiilor mele, cu abonamente cu tot, și te duce în patru pași până în App Store, în ritmul tău.

Dacă îți pregătești prima lansare, [fă diagnosticul gratuit](https://devoria.fr/ro/diagnostic): îți spune ce te blochează de fapt și îți trimite checklist-ul meu anti-respingere Apple. Pentru fișă, capturi de ecran și validare, pagina [publică o aplicație în App Store](https://devoria.fr/ro/expertise/publicare-aplicatie-app-store) reia fiecare pas.

## Întrebări frecvente

### De ce eas submit eșuează doar în CI?

În modul `--non-interactive`, comanda nu te poate întreba nimic. Are nevoie de `ascAppId` în profil și de o cheie API deja atașată aplicației, sau de cele trei câmpuri ale ei în `eas.json`. Pe calculatorul tău, te-ar fi întrebat toate astea.

### Trebuie să refac build-ul după o eroare eas submit?

Doar dacă Apple refuză binarul, cu un cod ITMS. Excepție: la ITMS-90054 și 90055, build-ul viza fișa greșită, ajunge să-l trimiți din nou spre cea corectă. Erorile de configurație și de cont se rezolvă în `eas.json`, în App Store Connect sau în contul tău Apple. Apoi trimiți același build, de exemplu cu `--latest` sau `--id`.

### Unde văd logurile unei trimiteri EAS Submit?

Pe pagina trimiterii, în dashboard-ul Expo. Expo recomandă să citești acolo logurile și bula „Build Annotations”. În terminal, adaugă `--verbose` ca să afișezi mereu logurile.

### Pot folosi eas submit cu un cont Apple gratuit?

Nu. Expo cere un cont Apple Developer plătit ca să trimiți o aplicație în App Store. Contul gratuit îți permite să testezi pe propriul iPhone, nu să folosești App Store Connect.

### Ce rol dau cheii API pentru eas submit?

Ghidul Expo dă cheii rolul Admin. Conform tabelului de roluri Apple, trimiterea de build-uri e permisă și rolurilor App Manager și Developer. Build-urile mele Expo merg cu o cheie de echipă cu rolul App Manager. Doar Account Holder și Admin pot genera o cheie de echipă.

### Ce înseamnă „Increment Build Number” în EAS?

Apple a refuzat build-ul cu codul ITMS-90189: numărul ăsta de build există deja pentru versiunea respectivă. Activează `"autoIncrement": true` în `eas.json` sau crește `ios.buildNumber`, apoi fă un build nou.


## Proiectul tău

[Review Kit](https://devoria.fr/ro/kits/app-review): Checklistul meu de review App Store, respingerile mele de la Apple rezolvate, checklistul pentru Google Play și trei skilluri Claude Code. 259 RON.

[iOS & Android Kit](https://devoria.fr/ro/kits/ios): Creează-ți aplicația de iPhone și Android cu Claude Code: codul de pornire al aplicațiilor mele, drumul până în store-uri și toate kiturile. 529 RON.

[Diagnostic: ce te desparte de aplicația ta de iPhone](https://devoria.fr/ro/diagnostic): 7 întrebări, 60 de secunde: afli ce te blochează de fapt să-ți publici aplicația de iPhone, traseul tău în 4 etape și kitul potrivit pentru tine.
