eas submit iOS 常見錯誤與修正方法
作者:Mehdi Azizi
發布於 ,10 分鐘
eas submit 失敗?EAS 與 App Store Connect 的實際錯誤訊息、原因與修正:ascAppId、API 金鑰、Apple 合約、ITMS 代碼。
當 eas submit --platform ios 失敗時,錯誤訊息幾乎都會告訴你該往哪裡找。不是你的 EAS 設定不完整,就是你的 Apple 帳號卡住了,要不然就是 Apple 拒收了你的二進位檔。前兩種情況幾分鐘就能修好,不用重新 build。第三種可以從 ITMS 代碼認出來,而且幾乎都需要重新 build。
我用 Expo 和 EAS 發布我的 iOS app,包括 Solys、TradaZen 和 Nolera。這裡引用的訊息都是從 EAS CLI 的原始碼複製來的,來源是 Expo 官方 GitHub 儲存庫,我在 2026 年 11 月 3 日重新看過。Expo 舊論壇現在已經導向 Discord,所以原始碼仍是最可靠的來源。如果要看完整流程,從 eas.json 檔案到送審,請先讀 EAS Submit iOS:把 Expo app 發布到 App Store。這篇專門講修錯。
eas submit 做了什麼,又需要什麼
根據 Expo 文件,這個指令會把你的 .ipa 檔案上傳到 App Store Connect。Apple 處理完之後,build 會出現在 TestFlight,通常要 10 到 15 分鐘。它不會把你的 app 送去審查:這一步還是要在 App Store Connect 裡自己做。
Expo 關於 iOS 上傳的頁面列出三個前提:
- 付費的 Apple Developer 帳號,任何上傳到 App Store 的動作都需要;
- bundle identifier,寫在
ios.bundleIdentifier; - 已安裝 EAS CLI,並登入你的 Expo 帳號。
若要在非互動模式下上傳,同一頁還補充了兩項設定:
ascAppId,寫在eas.json的submit設定檔裡,也就是你 App Store Connect 頁面的編號;- 一把 App Store Connect API 金鑰,可以由 EAS 管理,也可以自己提供。建立、角色與撤銷的細節請看 App Store Connect API 金鑰(.p8)。
最精簡的設定檔只要幾行。下面的值是假的:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890"
}
}
}
}
如果 EAS 已經保管你的 API 金鑰,這個設定檔就夠了。我大部分的 app 都是這樣。
讀懂訊息:三類錯誤
找修正方法之前,先看指令是在哪個時間點停下來的。這張表是我每次失敗時都會套用的判斷方式。
| 失敗時間點 | 類別 | 需要重新 build? |
|---|---|---|
| 尚未上傳任何東西之前 | EAS 設定 | 不用 |
| 連線 Apple、建立 app 頁面 | Apple 帳號 | 不用 |
| 上傳之後,出現 ITMS-90xxx | 二進位檔被拒 | 幾乎都要 |
詳細內容可以在 Expo 儀表板裡該次提交的頁面查看。Expo 建議在那裡讀日誌,並留意「Build Annotations」提示框,它會標出常見的失敗原因。在終端機裡,根據 EAS CLI 參考文件,加上 --verbose 選項就會一律顯示 EAS Submit 的日誌。
EAS 設定錯誤
「Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode.」
你用 --non-interactive 執行指令(例如在 CI 裡),而設定檔裡沒有 ascAppId。這時 EAS CLI 的程式碼會直接停止:它沒辦法問你問題,也沒辦法替你建立 app 頁面。
修正:把你 app 頁面的編號抄進 ascAppId。Expo 說明了在哪裡找:在 App Store Connect 打開你的 app,再進入 App Information。就是 General Information 底下的 Apple ID 欄位,大約十位數的數字。它不是你的 Apple 電子郵件,也不是你的 bundle identifier。
在 Nolera 上,沒有 ascAppId 時,指令會要我登入 Apple Developer 工作階段,而那個工作階段會過期。自從把編號寫進 eas.json,上傳就再也不會問任何東西了。
在 build 之前加上
ascAppId,不要在 build 之後。到 SDK 57 為止,Expo 計算的指紋一律包含eas.json。Vigie 的 runtime version 採用fingerprint策略,我在 build 之後才加這個編號,指紋就變了:之後發布的更新永遠不會送到已安裝的 build。根據 Expo 的版本紀錄,從 SDK 58 起,指紋的預設設定balanced會忽略eas.json。
「App Store Connect API Keys cannot be set up in --non-interactive mode.」
你的設定檔裡沒有金鑰,EAS 也沒有任何金鑰綁定你的 app。Expo 有說明:在非互動模式下,指令無法向你索取金鑰,就會帶著這個訊息失敗。
有兩種修正方式:
- 讓 EAS 建立並保管金鑰。在你的電腦上以互動模式執行一次
eas credentials --platform ios,讓它替你的 app 設定一把 App Store Connect API 金鑰。 - 自備金鑰,填入
ascApiKeyPath、ascApiKeyIssuerId和ascApiKeyId。根據 eas.json 參考文件,這三個欄位都接受環境變數,例如$ASC_API_KEY_PATH。
在我最新的 app 上,--auto-submit 選項要我提供 Apple ID 來建立它的上傳金鑰。我把自己金鑰的三個欄位放進工作副本的設定檔裡,從來不 commit。然後用 --id 和 --non-interactive 上傳已完成的 build。
「EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.」
這個變數裡放的不是 App 專用密碼,常常是你的 Apple 密碼本身。EAS CLI 在上傳之前就會檢查這個格式。
根據 Apple 支援說明,App 專用密碼要在 account.apple.com 的 App-Specific Passwords 區塊產生,而且要開啟雙重認證。只要你更改 Apple 帳號密碼,它就會被撤銷。Expo 認為這種方式不如 API 金鑰安全,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 更新了某份合約,但沒有人同意。根據 Apple 的角色表,只有帳號持有人(Account Holder)能同意合約。EAS 的程式碼會請他到 App Store Connect 的 Business 頁面處理,若 Apple 有要求,再到 developer.apple.com 的帳號頁面處理。然後重新執行指令。付費 app 的合約有獨立的指南:App Store Connect 的 Paid Apps Agreement。
「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 會把它在 Revoked 底下顯示 30 天:你必須重新產生一把。
「App Store Connect app for application identifier … was not found.」
用你的金鑰找不到 ascAppId 指向的 app 頁面。EAS 會請你檢查這個編號,並確認金鑰在正確的帳號裡確實有這個 app 的權限。它甚至會列出幾個用這把金鑰看得到的 app。用 Apple 自己的上傳工具時,同樣的問題會顯示成「No suitable application records were found」。
常見原因有三個,其中兩個出自 Apple 論壇的這篇討論:
- app 頁面不存在。在 App Store Connect 建立它,或拿掉
ascAppId,讓指令幫你建立。 - 編號來自另一個帳號。你複製了別的團隊或別的專案的
ascAppId。 - 使用者沒有這個 app 的權限。App Manager 或 Developer 可能只被開放部分 app。團隊金鑰則可以存取帳號內所有 app。
「… is not available to team」或「… is not available to provider」
這個訊息會在 EAS 因為沒有 ascAppId 而替你建立 app 頁面時出現。bundle identifier 已經被其他團隊用走了。EAS 會請你在 app 設定裡更改它,然後重新執行。
「App name "…" is already taken. Using generated name "…"」
這不是失敗。當名稱在 App Store 上已被使用,EAS 會隨機加上六個字元再試一次,最多五次。之後你可以在 App Store Connect 裡改名。要避免這種情況,請在第一次上傳前,在設定檔裡填好 appName 和 language:沒有 language 的話,主要語言會是 en-US。
二進位檔錯誤:ITMS 代碼
上傳之後,Apple 會處理 build。如果被拒,日誌會列出一個或多個 ITMS 代碼。以下是 EAS 上傳步驟能辨識並解讀的代碼:
| ITMS 代碼 | Apple 拒絕的原因 | 修正方式 |
|---|---|---|
| 90189 | build 編號已被使用 | autoIncrement |
| 90062, 90186, 90478 | 版本已關閉或已被超過 | 提高 version |
| 90683 | 缺少權限說明文字 | ios.infoPlist |
| 90725 | iOS SDK 太舊 | iOS 映像檔或 Expo SDK |
| 90054, 90055 | bundle 與目標 app 頁面不符 | 修正 ascAppId |
| 90022, 90023, 90391, 90713 | 圖示缺少或宣告錯誤 | 檢查圖示 |
| 90771 | 缺少背景任務識別碼 | ios.infoPlist |
從這些訊息整理出三點補充:
- build 編號在同一版本內必須唯一。遇到 90189,EAS 建議在
eas.json加上"autoIncrement": true。詳情請看 build 編號與版本。 - 遇到 90725,EAS 建議在
eas.json選用較新的 iOS 映像檔,必要時升級到仍受支援的 Expo SDK。 - 遇到 90771,代表你的 Info.plist 宣告了
processing背景模式,卻沒有BGTaskSchedulerPermittedIdentifiers這個鍵。
除了 90054 和 90055 只要指向正確的 app 頁面或換一個 build 之外,修正都會動到二進位檔:重新 build,再重新上傳。有兩個代碼有專屬指南:Expo 的 ITMS-90683 和 ITMS-90725。
2026 年 9 月底,Solys 的一個 build 在交付時因 ITMS-90683 被拒。我整理設定檔時刪掉了一句照片權限說明。Solys 根本沒用到照片,但專案裡有個函式庫會呼叫 iOS 的 Photos API。Apple 分析的是二進位檔,不是實際用途:從那之後,我再也不刪這些說明文字了。
至於 Missing Compliance 狀態,它不是上傳錯誤。它代表缺少你的加密聲明,說明請見 EAS 發布指南。
我每次上傳前的檢查清單
ascAppId已寫在submit設定檔裡,而且是在 build 之前加的。- API 金鑰由 EAS 管理,或它的三個欄位指向放在儲存庫以外的
.p8。 - Account Holder 已在 App Store Connect 同意最新合約。
- 已啟用
autoIncrement,搭配"appVersionSource": "remote",這是 EAS CLI 12 起 Expo 推薦的做法。 version高於最後一個已核准的版本。- 二進位檔裡每個敏感 API 都有對應的權限說明文字。
- 新 app 在第一次上傳前,已填好
appName和language。
順利送出你的第一個 app
這個指令只是其中一步。iOS & Android Kit 以我自己 app 的 Starter Code 為基礎,包含訂閱功能,分四個步驟帶你一路到 App Store,照你自己的節奏來。
如果你正在準備第一次上架,來做免費診斷:它會告訴你真正卡住你的是什麼,並寄給你我的 Apple 防退件檢查清單。關於 app 頁面、截圖與審核,在 App Store 上架 app 這頁會逐步說明每個步驟。
常見問題
為什麼 eas submit 只在 CI 裡失敗?
在 --non-interactive 模式下,指令沒辦法問你任何問題。它需要設定檔裡的 ascAppId,以及一把已綁定 app 的 API 金鑰,或是 eas.json 裡的三個金鑰欄位。在你自己的電腦上,它會直接問你這些問題。
eas submit 出錯後需要重新 build 嗎?
只有在 Apple 以 ITMS 代碼拒收二進位檔時才需要。例外:ITMS-90054 和 90055 代表 build 指向了錯誤的 app 頁面,只要重新上傳到正確的頁面就好。設定與帳號錯誤可以在 eas.json、App Store Connect 或你的 Apple 帳號裡修正。然後重新上傳同一個 build,例如用 --latest 或 --id。
在哪裡看 EAS Submit 上傳的日誌?
在 Expo 儀表板裡該次提交的頁面。Expo 建議在那裡讀日誌和「Build Annotations」提示框。在終端機裡,加上 --verbose 就會一律顯示日誌。
可以用免費 Apple 帳號使用 eas submit 嗎?
不行。Expo 要求付費的 Apple Developer 帳號才能把 app 上傳到 App Store。免費帳號只能在你自己的 iPhone 上測試,不能使用 App Store Connect。
eas submit 的 API 金鑰要給什麼角色?
Expo 的指南給金鑰 Admin 角色。根據 Apple 的角色表,App Manager 和 Developer 角色也能上傳 build。我的 Expo build 用的是 App Manager 角色的團隊金鑰。只有 Account Holder 和 Admin 能產生團隊金鑰。
EAS 裡的「Increment Build Number」是什麼意思?
Apple 以 ITMS-90189 代碼拒收了 build:這個版本已經有相同的 build 編號。在 eas.json 啟用 "autoIncrement": true,或提高 ios.buildNumber,然後重新 build。

