eas submit iOS: συχνά σφάλματα και πώς τα διορθώνεις
Από Mehdi Azizi
Δημοσιεύτηκε στις , 10 λ.
Το eas submit αποτυγχάνει; Τα πραγματικά μηνύματα του EAS και του App Store Connect, η αιτία τους και η διόρθωσή τους.
Όταν το eas submit --platform ios αποτυγχάνει, το μήνυμα σχεδόν πάντα σου λέει πού να κοιτάξεις. Είτε η ρύθμιση του EAS είναι ελλιπής, είτε μπλοκάρει ο λογαριασμός σου στην Apple, είτε η Apple απορρίπτει το binary. Οι δύο πρώτες περιπτώσεις διορθώνονται σε λίγα λεπτά, χωρίς νέο build. Την τρίτη την αναγνωρίζεις από έναν κωδικό ITMS, και σχεδόν πάντα θέλει νέο build.
Δημοσιεύω τις iOS εφαρμογές μου, ανάμεσά τους τις Solys, TradaZen και Nolera, με Expo και EAS. Τα μηνύματα που παραθέτω εδώ είναι αντιγραμμένα από τον πηγαίο κώδικα του EAS CLI, στο επίσημο αποθετήριο GitHub της Expo, όπως τον ξαναδιάβασα στις 3 Νοεμβρίου 2026. Το παλιό φόρουμ της Expo πλέον παραπέμπει στο Discord: ο κώδικας μένει η πιο αξιόπιστη πηγή. Για ολόκληρη τη διαδρομή, από το αρχείο eas.json μέχρι την υποβολή για έλεγχο, διάβασε πρώτα το EAS Submit iOS: δημοσίευση μιας εφαρμογής Expo στο App Store. Εδώ, επισκευάζουμε.
Τι κάνει το eas submit και τι χρειάζεται
Σύμφωνα με την τεκμηρίωση της Expo, η εντολή στέλνει το αρχείο .ipa σου στο App Store Connect. Το build εμφανίζεται στο TestFlight αφού το επεξεργαστεί η Apple, συνήθως σε 10 έως 15 λεπτά. Δεν υποβάλλει την εφαρμογή σου για έλεγχο: αυτό το κάνεις μόνος σου στο App Store Connect.
Η σελίδα της Expo για την αποστολή σε iOS αναφέρει τρεις προϋποθέσεις:
- έναν πληρωμένο λογαριασμό Apple Developer, απαραίτητο για κάθε αποστολή στο App Store·
- το bundle identifier στο
ios.bundleIdentifier· - το EAS CLI εγκατεστημένο και συνδεδεμένο στον λογαριασμό σου στην Expo.
Για αποστολή χωρίς αλληλεπίδραση, η ίδια σελίδα προσθέτει δύο ρυθμίσεις:
ascAppIdστο προφίλsubmitτουeas.json, τον αριθμό της καταχώρισής σου στο App Store Connect·- ένα κλειδί API του App Store Connect, που το διαχειρίζεται το EAS ή το δίνεις εσύ. Η δημιουργία, ο ρόλος και η ανάκλησή του εξηγούνται στο κλειδί API του App Store Connect (.p8).
Το ελάχιστο προφίλ χωράει σε λίγες γραμμές. Η τιμή είναι εικονική:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890"
}
}
}
}
Αν το EAS κρατάει ήδη το κλειδί API σου, αυτό το προφίλ αρκεί. Έτσι είναι στις περισσότερες εφαρμογές μου.
Διάβασε το μήνυμα: τρεις οικογένειες σφαλμάτων
Πριν ψάξεις τη διόρθωση, εντόπισε σε ποιο σημείο σταματάει η εντολή. Αυτός ο πίνακας είναι το πλέγμα που εφαρμόζω σε κάθε αποτυχία.
| Σημείο αποτυχίας | Οικογένεια | Νέο build; |
|---|---|---|
| Πριν από οποιαδήποτε αποστολή | Ρύθμιση EAS | Όχι |
| Σύνδεση με την Apple, δημιουργία καταχώρισης | Λογαριασμός Apple | Όχι |
| Μετά την αποστολή, κωδικός ITMS-90xxx | Απόρριψη binary | Σχεδόν πάντα |
Τις λεπτομέρειες τις βρίσκεις στη σελίδα της υποβολής, στο dashboard της Expo. Η Expo συνιστά να διαβάζεις εκεί τα logs και να εντοπίζεις το πλαίσιο «Build Annotations», που επισημαίνει τις συνηθισμένες αιτίες αποτυχίας. Στο τερματικό, η επιλογή --verbose εμφανίζει πάντα τα logs του EAS Submit, σύμφωνα με την αναφορά του 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 σταματάει τότε: δεν μπορεί ούτε να σε ρωτήσει, ούτε να δημιουργήσει την καταχώριση για σένα.
Διόρθωση: αντίγραψε τον αριθμό της καταχώρισής σου στο ascAppId. Η Expo λέει πού θα τον βρεις: στο App Store Connect, άνοιξε την εφαρμογή σου και μετά App Information. Είναι το πεδίο Apple ID, κάτω από General Information, ένας αριθμός με περίπου δέκα ψηφία. Δεν είναι ούτε το email της Apple σου, ούτε το bundle identifier.
Στη Nolera, χωρίς ascAppId, η εντολή μού ζητούσε μια συνεδρία Apple Developer, που λήγει. Από τότε που ο αριθμός μπήκε στο eas.json, η αποστολή δεν ζητάει τίποτα.
Πρόσθεσε το
ascAppIdπριν από το build, όχι μετά. Μέχρι το SDK 57, το αποτύπωμα (fingerprint) που υπολογίζει η Expo περιλαμβάνει πάντα τοeas.json. Στη Vigie, που η runtime version της ακολουθεί την πολιτικήfingerprint, η προσθήκη αυτού του αριθμού μετά από ένα build άλλαξε το αποτύπωμα: ένα update που θα δημοσιευόταν μετά δεν θα έφτανε ποτέ στο εγκατεστημένο build. Από το SDK 58, η προεπιλεγμένη ρύθμιση του αποτυπώματος,balanced, αγνοεί τοeas.json, σύμφωνα με το changelog της Expo.
«App Store Connect API Keys cannot be set up in --non-interactive mode.»
Το προφίλ σου δεν περιέχει κλειδί, και το EAS δεν έχει κανένα συνδεδεμένο με την εφαρμογή σου. Η Expo το διευκρινίζει: σε μη διαδραστική λειτουργία, η εντολή δεν μπορεί να σου ζητήσει κλειδί, και αποτυγχάνει με αυτό το μήνυμα.
Δύο πιθανές διορθώσεις:
- Άφησε το EAS να δημιουργήσει και να κρατήσει το κλειδί. Τρέξε μία φορά το
eas credentials --platform iosσε διαδραστική λειτουργία, στον υπολογιστή σου, και άφησέ το να ρυθμίσει ένα κλειδί API του App Store Connect για την εφαρμογή σου. - Φέρε το δικό σου κλειδί στα
ascApiKeyPath,ascApiKeyIssuerIdκαιascApiKeyId. Σύμφωνα με την αναφορά του eas.json, αυτά τα τρία πεδία δέχονται μεταβλητές περιβάλλοντος, όπως$ASC_API_KEY_PATH.
Στην τελευταία μου εφαρμογή, η επιλογή --auto-submit ήθελε ένα Apple ID για να δημιουργήσει το κλειδί αποστολής της. Έβαλα τα τρία πεδία του δικού μου κλειδιού στο προφίλ του τοπικού μου αντιγράφου, χωρίς να γίνουν ποτέ commit. Μετά έστειλα το ολοκληρωμένο build με --id και --non-interactive.
«EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.»
Η μεταβλητή περιέχει κάτι άλλο από app-specific password, συχνά τον ίδιο τον κωδικό της Apple σου. Το EAS CLI ελέγχει αυτή τη μορφή πριν από κάθε αποστολή.
Σύμφωνα με τη βοήθεια της Apple, ένα app-specific password δημιουργείται στο account.apple.com, στην ενότητα App-Specific Passwords, με ενεργό τον έλεγχο ταυτότητας δύο παραγόντων. Ανακαλείται μόλις αλλάξεις τον κωδικό του λογαριασμού σου στην Apple. Η Expo θεωρεί αυτή τη μέθοδο λιγότερο ασφαλή από το κλειδί API, που είναι η προεπιλεγμένη και προτεινόμενη μέθοδός της.
Τα σφάλματα του λογαριασμού 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. Ο κώδικας του EAS του ζητά να περάσει από τη σελίδα Business του App Store Connect και μετά, αν το προτείνει η Apple, από τον λογαριασμό του στο developer.apple.com. Μετά ξανατρέξε την εντολή. Η σύμβαση για τις πληρωμένες εφαρμογές έχει τον δικό της οδηγό: Paid Apps Agreement στο App Store Connect.
«App Store Connect rejected the API authentication credentials.»
Η Apple απάντησε με σφάλμα 401, NOT_AUTHORIZED. Το EAS αναφέρει τρεις αιτίες: ένα κλειδί που δεν είναι πια ενεργό, ένα κλειδί από άλλον λογαριασμό App Store Connect, ή λάθος Key ID, περιεχόμενο κλειδιού ή Issuer ID.
Έλεγξε τα δύο αναγνωριστικά στο App Store Connect, μενού Users and Access, καρτέλα Integrations. Σύμφωνα με την Apple, το Issuer ID εμφανίζεται στο πάνω μέρος της σελίδας και το Key ID στη λίστα των ενεργών κλειδιών. Ένα ανακληθέν κλειδί δεν ενεργοποιείται ποτέ ξανά. Η Apple το εμφανίζει για 30 ημέρες κάτω από Revoked: πρέπει να δημιουργήσεις καινούργιο.
«App Store Connect app for application identifier … was not found.»
Η καταχώριση στην οποία δείχνει το ascAppId δεν βρίσκεται με το κλειδί σου. Το EAS σου ζητά να ελέγξεις αυτόν τον αριθμό, και ότι το κλειδί έχει όντως πρόσβαση στην εφαρμογή στον σωστό λογαριασμό. Σου δείχνει μάλιστα μερικές εφαρμογές που φαίνονται με αυτό το κλειδί. Με τα εργαλεία αποστολής της Apple, το ίδιο πρόβλημα εμφανίζεται ως «No suitable application records were found».
Τρεις αιτίες επανέρχονται, δύο από τις οποίες αναφέρονται σε αυτό το νήμα στα φόρουμ της Apple:
- Η καταχώριση δεν υπάρχει. Δημιούργησέ την στο App Store Connect, ή αφαίρεσε το
ascAppIdγια να τη δημιουργήσει η εντολή. - Ο αριθμός είναι από άλλον λογαριασμό. Αντέγραψες το
ascAppIdάλλης ομάδας ή άλλου project. - Ο χρήστης δεν έχει πρόσβαση στην εφαρμογή. Ένας App Manager ή ένας Developer μπορεί να έχει περιορισμένη πρόσβαση σε ορισμένες εφαρμογές. Ένα κλειδί ομάδας, αντίθετα, έχει πρόσβαση σε όλες τις εφαρμογές του λογαριασμού.
«… is not available to team» ή «… is not available to provider»
Αυτό το μήνυμα εμφανίζεται όταν το EAS δημιουργεί την καταχώριση για σένα, επειδή λείπει το ascAppId. Το bundle identifier το έχει ήδη πάρει άλλη ομάδα. Το EAS σού ζητά να το αλλάξεις στις ρυθμίσεις της εφαρμογής σου και να ξανατρέξεις την εντολή.
«App name "…" is already taken. Using generated name "…"»
Δεν είναι αποτυχία. Όταν το όνομα είναι ήδη πιασμένο στο App Store, το EAS προσθέτει έξι τυχαίους χαρακτήρες και ξαναδοκιμάζει, έως πέντε φορές. Θα μετονομάσεις την καταχώριση αργότερα στο App Store Connect. Για να το αποφύγεις, συμπλήρωσε τα appName και language στο προφίλ πριν από την πρώτη αποστολή: χωρίς language, η κύρια γλώσσα είναι en-US.
Τα σφάλματα του binary: οι κωδικοί ITMS
Μετά την αποστολή, η Apple επεξεργάζεται το build. Αν το απορρίψει, το log αναφέρει έναν ή περισσότερους κωδικούς ITMS. Αυτοί είναι όσοι το βήμα αποστολής του EAS αναγνωρίζει και εξηγεί:
| Κωδικός ITMS | Τι απορρίπτει η Apple | Διόρθωση |
|---|---|---|
| 90189 | Αριθμός build που υπάρχει ήδη | autoIncrement |
| 90062, 90186, 90478 | Έκδοση κλειστή ή ήδη ξεπερασμένη | Αύξησε το version |
| 90683 | Λείπει το κείμενο άδειας (purpose string) | ios.infoPlist |
| 90725 | Πολύ παλιό iOS SDK | Image iOS ή SDK Expo |
| 90054, 90055 | Bundle διαφορετικό από την καταχώριση | Διόρθωσε το ascAppId |
| 90022, 90023, 90391, 90713 | Εικονίδια που λείπουν ή δηλωμένα λάθος | Έλεγξε τα εικονίδια |
| 90771 | Λείπουν τα αναγνωριστικά background tasks | ios.infoPlist |
Τρεις διευκρινίσεις από αυτά τα μηνύματα:
- Ο αριθμός build είναι μοναδικός ανά έκδοση. Για το 90189, το EAS προτείνει
"autoIncrement": trueστοeas.json. Όλα εξηγούνται στο αριθμός build και έκδοση. - Για το 90725, το EAS συνιστά να επιλέξεις πιο πρόσφατο iOS image στο
eas.jsonκαι, αν χρειαστεί, να περάσεις σε υποστηριζόμενο SDK της Expo. - Για το 90771, το Info.plist σου δηλώνει το background mode
processing, αλλά όχι το κλειδίBGTaskSchedulerPermittedIdentifiers.
Εκτός από τα 90054 και 90055, όπου αρκεί να στοχεύσεις τη σωστή καταχώριση ή άλλο build, η διόρθωση αφορά το binary: κάνε νέο build και στείλ' το ξανά. Δύο κωδικοί έχουν δικό τους οδηγό: ITMS-90683 με Expo και ITMS-90725.
Στα τέλη Σεπτεμβρίου 2026, ένα build της Solys απορρίφθηκε κατά την παράδοση για ITMS-90683. Είχα αφαιρέσει ένα κείμενο άδειας για τις φωτογραφίες σε ένα καθάρισμα του αρχείου ρυθμίσεων. Η Solys δεν χρησιμοποιεί φωτογραφίες, αλλά μια βιβλιοθήκη του project καλεί το Photos API του iOS. Η Apple αναλύει το binary, όχι την πραγματική χρήση: από τότε, δεν αφαιρώ ποτέ πια αυτά τα κείμενα.
Η κατάσταση Missing Compliance, πάλι, δεν είναι σφάλμα αποστολής. Λείπει η δήλωσή σου για την κρυπτογράφηση, που εξηγείται στον οδηγό δημοσίευσης με EAS.
Η checklist μου πριν από κάθε αποστολή
- Το
ascAppIdείναι στο προφίλsubmit, προστέθηκε πριν από το build. - Το κλειδί API το διαχειρίζεται το EAS, ή τα τρία πεδία του δείχνουν σε ένα
.p8αποθηκευμένο εκτός αποθετηρίου. - Ο Account Holder έχει αποδεχτεί τις τελευταίες συμβάσεις στο App Store Connect.
- Το
autoIncrementείναι ενεργό, με"appVersionSource": "remote", που προτείνει η Expo από το EAS CLI 12. - Το
versionείναι μεγαλύτερο από την τελευταία εγκεκριμένη έκδοση. - Κάθε ευαίσθητο API που υπάρχει στο binary έχει το κείμενο άδειάς του.
- Για νέα εφαρμογή, τα
appNameκαιlanguageείναι συμπληρωμένα πριν από την πρώτη αποστολή.
Στείλε την πρώτη σου εφαρμογή χωρίς να κολλήσεις
Η εντολή είναι μόνο ένα βήμα. Το iOS & Android Kit ξεκινά από τον βασικό κώδικα των εφαρμογών μου, μαζί με τις συνδρομές, και ακολουθεί τέσσερα βήματα μέχρι το App Store, με τον δικό σου ρυθμό.
Αν ετοιμάζεις την πρώτη σου κυκλοφορία, κάνε τη δωρεάν διάγνωση: σου λέει τι σε μπλοκάρει πραγματικά και σου στέλνει τη checklist μου κατά των απορρίψεων της Apple. Για την καταχώριση, τα screenshots και την έγκριση, η σελίδα δημοσίευση εφαρμογής στο App Store καλύπτει κάθε βήμα.
Συχνές ερωτήσεις
Γιατί το eas submit αποτυγχάνει μόνο σε συνεχή ενσωμάτωση;
Σε λειτουργία --non-interactive, η εντολή δεν μπορεί να σε ρωτήσει τίποτα. Χρειάζεται το ascAppId στο προφίλ και ένα κλειδί API ήδη συνδεδεμένο με την εφαρμογή, ή τα τρία πεδία του στο eas.json. Στον υπολογιστή σου, θα σου είχε κάνει αυτές τις ερωτήσεις.
Χρειάζεται νέο build μετά από σφάλμα του eas submit;
Μόνο αν η Apple απορρίψει το binary, με κωδικό ITMS. Εξαίρεση: στα ITMS-90054 και 90055, το build στόχευε λάθος καταχώριση, οπότε αρκεί να το ξαναστείλεις στη σωστή. Τα σφάλματα ρύθμισης και λογαριασμού διορθώνονται στο eas.json, στο App Store Connect ή στον λογαριασμό σου στην Apple. Μετά ξαναστέλνεις το ίδιο build, για παράδειγμα με --latest ή --id.
Πού βλέπω τα logs μιας αποστολής EAS Submit;
Στη σελίδα της υποβολής, στο dashboard της Expo. Η Expo συνιστά να διαβάζεις εκεί τα logs και το πλαίσιο «Build Annotations». Στο τερματικό, πρόσθεσε --verbose για να εμφανίζονται πάντα τα logs.
Μπορώ να χρησιμοποιήσω το eas submit με δωρεάν λογαριασμό Apple;
Όχι. Η Expo απαιτεί πληρωμένο λογαριασμό Apple Developer για να στείλεις εφαρμογή στο App Store. Ο δωρεάν λογαριασμός σού επιτρέπει να δοκιμάζεις στο δικό σου iPhone, όχι να χρησιμοποιείς το App Store Connect.
Τι ρόλο να δώσω στο κλειδί API για το eas submit;
Ο οδηγός της Expo δίνει στο κλειδί τον ρόλο Admin. Σύμφωνα με τον πίνακα ρόλων της Apple, η αποστολή builds επιτρέπεται και στους ρόλους App Manager και Developer. Τα Expo builds μου τρέχουν με κλειδί ομάδας με ρόλο App Manager. Μόνο ο Account Holder και οι Admins μπορούν να δημιουργήσουν κλειδί ομάδας.
Τι σημαίνει «Increment Build Number» στο EAS;
Η Apple απέρριψε το build με τον κωδικό ITMS-90189: αυτός ο αριθμός build υπάρχει ήδη για αυτή την έκδοση. Ενεργοποίησε το "autoIncrement": true στο eas.json, ή αύξησε το ios.buildNumber, και μετά κάνε νέο build.

