FlutterビルドのImproperly formatted define flagエラーの原因と解決方法

Flutter define flagエラーの原因と対処
  • URLをコピーしました!

Flutter製iOSアプリをXcodeでArchiveしたり、IPAを作ったりするときに、Improperly formatted define flag というエラーで止まると、原因が分かりにくく感じられます。
ログには PhaseScriptExecution の失敗や xcode_backend.sh の実行失敗が並び、「CocoaPodsが壊れた」「iosフォルダを作り直すべき」と思いがちです。

実際には、多くの場合は --dart-define や DART_DEFINES の受け渡しが崩れていることが起点です。
本記事では、エラーの意味、確認コマンド、原因仮説ごとの対処を、事実と未検証の推測を分けて整理します。

ポイント

先に Flutter や CocoaPods の再インストール、ios フォルダの再生成へ進まないでください。

まず dart-define の指定場所、DART_DEFINES の値、環境変数、SDK 版を事実として確認し、仮説を1つずつ潰す方が安全です。

目次

Improperly formatted define flagとは

Improperly formatted define flag は、Flutter ツールがコンパイル時定数(dart-define)を解釈できないときに出すメッセージです。
Xcode の Archive や IPA 作成では、Run Script から xcode_backend.sh 経由で flutter assemble が呼ばれ、その中で define の解析に失敗するとこの文言になります。

公式の iOS リリース手順でも、配布用ビルドは Xcode ワークスペースや flutter build ipa を使う流れが案内されています。
普段の flutter run では成功するのに、Archive だけ失敗する、という報告も GitHub Issue 上で確認できます。

エラー直後のログに AssembleCommand._parseDefines が出ている場合は、ほぼ dart-define の書式問題です。
逆に、パスにカンマや記号がある、署名設定が違う、といった別系統の失敗もあります。
まずは「define 解析で落ちているか」をログで確認してください。

–dart-defineとDART_DEFINESの関係

CLI では --dart-define KEY=VALUE でコンパイル時定数を渡せます。
公式ドキュメントでも、Sentry の DSN を --dart-define で渡す例や、CI で環境変数を同じフラグ経由で渡す例が紹介されています。

Xcode からビルドする場合、同じ情報は多くの環境で User-Defined の DART_DEFINES、または ios/Flutter/Generated.xcconfig や flutter_export_environment.sh に載ります。
コミュニティ知見として、Xcode 側の DART_DEFINES には KEY=VALUE を Base64 したものが入り、Flutter CLI が生成ファイルへ書き出す、という説明が広く共有されています。

ここを手動でプレーンテキストのまま書いたり、空のまま残したり、二重にエンコードしたりすると、解析側が「不正な define」と判断しやすくなります。
「CLIでは通るが Xcode Archive だけ落ちる」ときは、この経路の差分を疑うのが近道です。

確認対象見る場所の例よくある崩れ方
--dart-defineターミナル、CI スクリプト、IDE の Run 設定KEY=VALUE でない、引用符の付け方が壊れている
DART_DEFINESXcode Build Settings(User-Defined)、xcconfig空、プレーンテキスト、不正な Base64、余分な空白
生成ファイルios/Flutter/Generated.xcconfig、flutter_export_environment.shexport "DART_DEFINES=" の空値、古い内容のまま
シェル環境変数ターミナルの env、CI の Env意図しない DART_* が混入
Flutter SDKflutter --version特定版で空 define や Base64 周りに既知の不具合報告

切り分け手順(再インストールより先に)

設定を消したり SDK を入れ直したりする前に、次の順で事実を集めます。
実行ディレクトリは、特に断らない限り Flutter プロジェクトのルート(pubspec.yaml がある場所)です。

1. エラー文言と失敗フェーズを控える

Xcode の Report navigator、またはターミナルのビルドログから、次をコピーします。

  • 全文の Improperly formatted define flag 行(直後に続く値があればそれも含む)
  • xcode_backend.sh や flutter assemble が出ているか
  • _parseDefines などのスタックが出ているか

「Failed to package …」だけが見えても、詳細ログを開くと define の値が付いていることがあります。
値がある場合は、その文字列が空か、Base64 か、プレーンな KEY=VALUE かをメモしてください。

2. プロジェクト内の dart-define 指定を探す

用途は、「誰がどこで define を渡しているか」を一覧化することです。
プロジェクトルートで次を実行します。

grep -R "dart-define" .

Makefile、シェル、GitHub Actions、Fastlane、.vscode/launch.json などにヒットすることが多いです。
ios/ 配下の生成物ばかりがヒットする場合は、手動指定より生成ファイル側を重点確認します。

3. シェルに残っている DART 系環境変数を確認する

用途は、「今のターミナル/CI シェルが、意図しない DART 系変数を持っていないか」を見ることです。
ビルドを実行しているのと同じシェルで、次を実行します。

env | grep DART

何も出ないのは正常なことも多いです。
DART_DEFINES が空文字で export されている、または想定外の値が入っている場合は、そのシェル経由のビルドをいったん疑ってください。

4. Flutter SDKの版を記録する

用途は、後述の既知不具合報告と突き合わせるための版情報を残すことです。
プロジェクトルート、またはいつもの PATH が通ったシェルで実行します。

flutter --version

特定バージョンだけが唯一の原因、と決めつける必要はありません。
ただし GitHub 上では、空の --DartDefines= を拒否する挙動や、Base64 値の検証まわりについて Issue/修正 PR が公開されています。

5. 生成ファイルのDART_DEFINESを目視する

用途は、Xcode が実際に読む値が空/不正になっていないかを確認することです。
標準的なアプリ構成では、プロジェクトルートから次を確認します。

grep -n "DART_DEFINES" ios/Flutter/Generated.xcconfig
grep -n "DART_DEFINES" ios/Flutter/flutter_export_environment.sh

add-to-app 構成では .ios/Flutter/ 配下になることがあります。
export "DART_DEFINES=" のように右辺が空、またはファイル自体が古い/欠落している、という報告が Issue 上であります。

原因別の対処(断定せず仮説ごとに)

ここからは「こうすれば必ず直る」ではなく、前段で集めた事実に合わせて試す対策です。
1つ試したら、同じ Archive/IPA 手順で再現確認し、結果をメモしてください。

仮説A:DART_DEFINESが空、または生成ファイルが古い

事実として確認できることとして、GitHub Issue #178452 では、flutter pub get 後に DART_DEFINES が空のまま残り、Xcode Archive が失敗する報告があります。
同じスレッドでは、flutter build ios を一度走らせて生成ファイルを作り直したあと Archive が通った、という再現報告も複数あります。

試す手順の例です(プロジェクトルート)。

flutter pub get
flutter build ios

完全にビルドを終える必要はない、途中キャンセルでも生成が進めばよい、という報告もありますが、環境差があります。
生成後にもう一度 Generated.xcconfig / flutter_export_environment.sh の DART_DEFINES を確認してから Archive してください。

手動で export "DART_DEFINES=..." をコピペしただけでは直らなかった、という報告もあるため、手編集より Flutter コマンドでの再生成を優先した方がよいです。

仮説B:XcodeのDART_DEFINESを手動設定している

Build Settings の User-Defined に DART_DEFINES を自分で入れている場合、次を確認します。

  • 値はプレーンな API_URL=... ではなく、Flutter が期待する形式(多くの場合 Base64)か
  • 余分な引用符、前後空白、改行が入っていないか
  • 複数値をカンマ連結する場合、生成物と同じ区切りになっているか

Issue #179578 では、手動で入れた Base64 の扱いや引用符の有無で「Improperly formatted define flag」が出る報告があり、後続のツール修正で解消した、とクローズされています。
手元で同じ症状なら、まず手動値を外し、CLI の --dart-define から生成される値だけにした状態で再試行するのが安全です。

仮説C:CLIの–dart-define書式が崩れている

KEY=VALUE 形式になっていない、= が無い、シェル展開で値が空になる、といったケースです。
CI では変数が未設定のまま --dart-define FOO=$FOO となり、空 define を渡していることがあります。

確認例(プロジェクトルート)。

flutter build ipa --dart-define=ENV=staging

公式の CD ガイドでも、秘密情報は CI の暗号化変数を --dart-define で渡す流れが示されています。
変数が空でないこと、ログに秘密情報を丸出ししないことをセットで確認してください。

仮説D:Flutter SDK側の既知不具合に当たっている

Issue #178452 では、空の dart define を flutter assemble が拒否する問題が議論され、空 define を許容する修正が取り込まれた、と記録されています。
コメント上では hotfix 後の stable で解消した、という案内もあります。

ここは「その版が悪い」と断定するのではなく、次のように扱ってください。

  • flutter --version の結果を控える
  • 同じエラー文言の Issue/CHANGELOG/PR を照合する
  • 可能なら、問題が修正済みと案内されているチャネル/版で再現比較する

本番配布用 CI で master を常用するのは別リスクがあるため、チャネル変更は一時的な切り分けか、修正が入った stable/beta の確認に留めるのが無難です。

仮説E:別要因(パス・Pods・署名)が混ざっている

define 以外でも Xcode ビルドは失敗します。
プロジェクトパスにカンマや特殊記号がある、Pods のインストール不足、署名設定ミスなどは、似た「スクリプト失敗」に見えることがあります。

ただし本エラー文言が define 解析由来であることがログで明らかなら、先に仮説 A〜D を潰すべきです。
pod deintegrate や ios フォルダ削除は、原因が特定できてからに留めてください。

解決しないときに追加で確認すること

ここまでの手順でも直らない場合は、次の情報を揃えてから Issue 検索やチーム共有に進むと早いです。

  • flutter doctor -v の全文
  • flutter --version のチャネルと版
  • 失敗ログの Improperly formatted define flag 行(続く値を含む)
  • grep -R "dart-define" . と env | grep DART の結果
  • Generated.xcconfig / flutter_export_environment.sh の DART_DEFINES(秘密値はマスク)
  • 再現手順が flutter build ipa か、Xcode の Product → Archive か、Xcode Cloud か
  • add-to-app か通常の Flutter アプリか
  • 最近変えたもの(SDK 更新、CI 変更、手動の Build Settings)

類似の「ログから原因を切り分ける」記事としては、AWS Lambda のハンドラー未検出や署名付き URL の 403 も、事実確認の順序が参考になります。

まとめ

Improperly formatted define flag は、Xcode Archive/IPA 作成時に Flutter が dart-define を解釈できないときに出やすいエラーです。
再インストールより先に、grep -R "dart-define" .、env | grep DART、flutter --version、生成ファイルの DART_DEFINES で事実を集め、空値・手動設定・CLI 書式・SDK 既知不具合の順で仮説を潰してください。

特定の Flutter バージョンを唯一の原因と決めつけず、公式ドキュメントと Issue/修正記録で裏付けながら進めると、安全に切り分けできます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次