macOS Sequoia+Xcode 16.2 のMacで、VS Codeから.NET 9(.NET MAUI)をデバッグしようとすると、UnauthorizedAccessExceptionで止まることがあります。原因はだいたい「~/.dotnet配下の権限」か「MAUIワークロードの破損」。現場で直った手順を、確認ポイント込みでまとめます。
症状:VS Codeから.NET MAUIをデバッグできず、toolpath.sentinelで落ちる
今回の相談内容は、Mac(macOS Sequoia)に.NET 9(MAUIワークロード)を入れ、VS Codeからデバッグ実行しようとしたところ、次の例外で止まるというものです。
System.UnauthorizedAccessException: Access to the path '/Users/<ユーザー名>/.dotnet/9.0.201.toolpath.sentinel' is denied.
ポイントは2つあります。
- エラーパスが ~/.dotnet(ユーザーホーム配下)を指している
- 対象が 9.0.201.toolpath.sentinel という「小さな目印ファイル(sentinel)」である
そして「.dotnetフォルダを見ても 9.0.201.toolpath.sentinel が存在しない」という状況になりがちです。これは、存在しないのではなく、作成しようとして作れない(または作られても読めない)状態である可能性が高いです。
| 項目 | 内容 | 困ること |
|---|---|---|
| 環境 | Mac(macOS Sequoia)+Xcode 16.2+.NET 9(MAUI)+VS Code | iOSシミュレーター/実機のデバッグまで到達しない |
| エラー | UnauthorizedAccessException(toolpath.sentinelへのアクセス拒否) | ビルドや起動の前段でCLIが止まる |
| よくある勘違い | 「ファイルが無い=どこかに隠れている」 | 実際は権限・所有者・ワークロード破損が原因で作成できていないことが多い |
toolpath.sentinelとは何か:なぜここで止まるのか
*.toolpath.sentinel は、.NET SDK(今回なら 9.0.201)が実行時に「ユーザー環境の初期化」や「ツールパス(主に ~/.dotnet/tools など)に関する状態管理」をする際に作成するマーカーファイルの一種です。サイズは小さくても、作成/更新に失敗すると例外で落ちることがあります。
つまり、この例外は「MAUIそのもののビルドが壊れている」だけでなく、もっと手前の.NET CLIがホームディレクトリ配下に書き込めない状態で起きます。VS Codeでデバッグしていても、裏では dotnet コマンドが動いているため、そこで止まるとVS Code側は何もできません。
ファイルが見つからないのにアクセス拒否になるのは、次のようなケースで説明できます。
- ~/.dotnet ディレクトリ自体が書き込み不可(所有者がrootになっている、権限が狭い、ACLが付いている)
- 過去に
sudo dotnet ...を実行してroot所有のファイルが混入し、一般ユーザー実行で作成/更新できなくなった - MAUIワークロードの導入途中で壊れ、内部処理が途中で止まりやすい状態になっている(結果としてsentinel作成にも失敗しやすい)
原因として多いパターンと、切り分けの観点
同じエラーメッセージでも、原因は大きく分けて「権限」と「ワークロード不整合」に集約されます。まずは典型パターンを押さえ、チェックコマンドで当たりを付けるのが早道です。
| 疑うポイント | ありがちな原因 | 確認コマンド例 | 対処の方向性 |
|---|---|---|---|
| ~/.dotnetの権限 | root所有、書き込み権限が無い、ACLが原因 | ls -ld ~/.dotnet | 所有者/権限を正す、sudo実行の混在をやめる |
| ワークロードの破損 | インストールが中断、更新で失敗、SDK差し替え | dotnet workload list | repair→update→installで整合性を取り直す |
| SDKバージョンのズレ | VS Codeが参照するdotnetが別物(brewと公式が混在など) | which dotnet / dotnet --info | PATHを整理、不要なSDKを整理、global.jsonで固定 |
| Xcode周りの前提 | 初回起動が未完了、ライセンス未同意、CLT未設定 | xcodebuild -version / xcode-select -p | Xcodeの初期設定を完了させる |
解決手順:workload repair / update でMAUI環境を修復する
質問者の環境で実際に解消したのは、ワークロードの修復→更新→確認→(必要なら)MAUI追加の流れです。まずはターミナルで、以下を上から順に実行します。
- ワークロードの修復
sudo dotnet workload repair途中で壊れた状態や、参照先がズレた状態を修復します。workload関連のファイルが揃っていないときに、まず効くことが多い手順です。 - ワークロードの更新
sudo dotnet workload update修復後に最新版へ更新します。.NET 9系は更新が頻繁なので、repairだけで止めずupdateまで通して整合性を取りやすくします。 - インストール済みワークロードの確認
dotnet workload list一覧にmauiが含まれているかを確認します。ここで表示されていなければ、MAUIが正しく入っていない(または壊れて認識されていない)可能性が高いです。 - もし
mauiが無い場合はインストールsudo dotnet workload install mauiMAUIワークロードを入れ直します。iOSだけを触るつもりでも、MAUIの土台が入っていないとVS Code側のデバッグ準備が進みません。
上記を通すことで、MAUI関連ワークロードが正しく整備され、結果として 9.0.201.toolpath.sentinel 生成周りの問題も解消し、VS Codeからデバッグできる状態に戻ることがあります。
この手順が効きやすい理由
workloadは「SDK本体」とは別のレイヤーで、テンプレート・ターゲット・ツール群を追加します。途中で失敗すると、VS Code側でどれだけ設定を見直しても、そもそも dotnet の内部処理が例外で止まってしまいます。repair/updateで“部品の欠落”を埋めることで、sentinel作成の前提(正常な実行フロー)に戻せます。
補足:~/.dotnet の権限を確認しておくと再発しにくい
workload修復で直っても、根っこが「権限」だと再発することがあります。特に、過去に一度でも sudo dotnet ... を実行した端末は、ユーザーフォルダ配下にroot所有ファイルが混ざることがあり、今回のような “Access is denied” が起きやすくなります。
権限・所有者を確認する
ls -ld ~/.dotnet
表示結果の所有者が自分(通常はログインユーザー)になっているか、書き込み権限があるかを確認します。例えば、所有者がrootになっている場合は要注意です。
所有者がおかしいときの一例(自己管理マシンの場合)
sudo chown -R $(whoami) ~/.dotnet
このコマンドは ~/.dotnet 配下を自分の所有に戻します。会社支給PCや複数ユーザーで共有しているMacでは運用ルールがある場合もあるため、社内ルールに合わせて実施してください。
「root所有ファイルが混入しているか」をピンポイントで探す
sudo find ~/.dotnet -user root -maxdepth 3 -print
この結果が大量に出る場合、今後のためにも所有者の整理をしておくとトラブルが減ります(MAUIに限らず、.NETのツールインストール全般で詰まりにくくなります)。
確認:SDKバージョンと、VS Codeが参照するdotnetの整合性
エラーのパスに 9.0.201 と出ているのに、自分の認識では 9.0.200 を入れたつもり、という“ズレ”が起きることがあります。VS Codeが参照する dotnet が期待と違うと、workloadの状態も別物扱いになり、結果としてデバッグが不安定になります。
次の3点はセットで確認しておくのがおすすめです。
which dotnet
dotnet --list-sdks
dotnet --info
| チェック項目 | 見るところ | ズレがあると起きやすいこと |
|---|---|---|
which dotnet | PATH上で最優先のdotnet実体 | brew版/公式版が混在し、意図しないSDKを使う |
dotnet --list-sdks | 9.0.201などのSDKが存在するか | workload repairしたのに別SDKを実行して無効化される |
dotnet --info | OS/アーキ/SDKの場所/環境変数 | arm64とx64の混在、インストール先の取り違えが見える |
VS Codeは基本的に「ターミナルで動くdotnet」をそのまま使います。ターミナルで dotnet が期待通り動く状態を作ることが、結果的にVS Codeのデバッグ復旧の最短ルートです。
VS Code側でやっておくと安定するポイント
workload修復後は、VS Code側も次を実施しておくと反映が早く、ハマり直しを防げます。
- VS Codeを完全終了→再起動(ウィンドウを閉じるだけでなくプロセスも終了)
- ターミナルを開き直す(PATHの変更や環境変数の反映のため)
- MAUIプロジェクト直下でビルド確認(デバッグ前にCLIを素通りさせる)
dotnet build
dotnet run
ここで同じ例外が再現しなければ、VS Code側の問題というより「.NET CLI周りの問題」が解消したと判断できます。逆に、ターミナルでも同じエラーが出る場合は、VS CodeではなくOS上のファイル権限やworkload状態が原因です。
それでも直らないときの追加チェック
repair/update/installで改善しない場合は、次の“詰まりポイント”を上から潰します。特にmacOS+Xcode+MAUIは依存関係が多いので、原因が一段ズレて見えることがあります。
Xcodeの初回セットアップとライセンス
Xcodeをアップデート直後に入れただけで、初回起動(追加コンポーネントのインストール)が終わっていないと、iOS周りのツールチェーンが不完全なままになります。
- Xcodeを一度起動して、追加コンポーネントのインストールを完了させる
- 必要に応じてライセンス同意を済ませる
sudo xcodebuild -license accept
xcode-select -p
xcodebuild -version
ワークロードキャッシュの掃除(破損疑いが強いとき)
workloadの状態が中途半端なまま残っていると、repair/updateが通っても内部で引きずることがあります。次は“やり過ぎない範囲”の掃除です。
dotnet workload clean
dotnet nuget locals all --clear
その後、再度 dotnet workload repair → dotnet workload update を実行し直します。
.NET SDKのインストール方法が混在していないか
Macでは、公式インストーラー版とHomebrew版を併用してしまい、PATH上の優先順位で「想定と違うdotnet」が動くケースがあります。“直したはずなのに直らない”ときは、まずどのdotnetを使っているかの確認が重要です。
| 状況 | 症状 | 確認ポイント | 対処の考え方 |
|---|---|---|---|
| brewと公式が混在 | ターミナルとVS CodeでSDKが違う | which dotnet が指すパス | 使う方を1つに寄せ、PATHを整理する |
| arm64/x64が混在 | workloadが見えたり見えなかったりする | dotnet --info のArchitecture | 端末のCPUに合わせて揃える(Apple Siliconならarm64が基本) |
| global.jsonが古い | 特定SDKに固定され、workloadが一致しない | リポジトリ直下の global.json | 固定を外す/更新する/チーム運用に合わせる |
よくある疑問:ファイルが見当たらないのに「アクセス拒否」になる理由
UnauthorizedAccessExceptionは、「既に存在するファイルを読めない」ケースだけでなく、新規に作成しようとして書き込めないケースでも発生します。今回の 9.0.201.toolpath.sentinel は、.NET SDKが必要なタイミングで作る“目印”なので、最初から存在しないこと自体は珍しくありません。
それでも例外になるのは、たとえば次のような“書けない理由”が隠れているためです。
- 所有者がrootになっている(過去のsudo実行や移行作業の影響)
- ディレクトリに書き込み権限が無い(権限ビット、ACL、管理ポリシー)
- iCloud Drive等の同期でホーム配下の状態が一時的に不安定(極端に遅い/ロックされる)
- ディスク容量不足や、セキュリティソフトによる隔離で作成が失敗している
「ファイルが無いからダウンロードして置けばいい」という話ではなく、dotnetが正常に書き込める状態に戻すのが本質です。workload repair/update と権限確認をセットで行うのは、このためです。
最短で復旧するためのチェックリスト
忙しいときは、次の順番で潰すと手戻りが少なくなります。特に「どこを直したらいいか分からない」場合ほど、上から機械的に確認するのが効きます。
| 手順 | やること | OKの目安 |
|---|---|---|
| dotnetの実体確認 | which dotnet / dotnet --info | 想定したSDK(9.0.201など)で動いている |
| 権限の一次確認 | ls -ld ~/.dotnet | 所有者が自分、書き込み可能 |
| workloadの修復 | dotnet workload repair(必要に応じてsudo) | エラーなく完走する |
| workloadの更新 | dotnet workload update(必要に応じてsudo) | 更新が完了し、破損が残らない |
| MAUIの有無 | dotnet workload list | maui が表示される |
| プロジェクトでの確認 | プロジェクト直下で dotnet build | 同じ例外が出ない |
| VS Code再起動 | VS Code/ターミナルを開き直す | デバッグが開始できる |
再発防止:MAUI開発で“権限トラブル”を避けるコツ
- 普段の
dotnet build/runをsudoで実行しない(ユーザーフォルダにroot所有が混ざる最大要因) - workload操作だけにsudoを限定し、実行後に
~/.dotnetの所有者を確認する - SDKの導入経路を統一する(公式インストーラーかbrewのどちらかに寄せる)
- プロジェクトでSDKを固定する場合はglobal.jsonを最新化し、workloadとセットで運用する
- Xcode更新後は一度起動してセットアップを完了させ、CLIから
xcodebuild -versionが通る状態にする
特に1つ目は効果が大きいです。sudo実行が必要な場面はゼロではありませんが、日常的にsudoを混ぜると、今回のような「本来ユーザー領域に作られるはずのファイルが作れない」事故が起きやすくなります。
まとめ:MacのVS Codeで.NET MAUIがデバッグできないときは、まずworkload整備と~/.dotnet権限を疑う
今回の 9.0.201.toolpath.sentinel へのアクセス拒否は、MAUI固有の難しさというより、.NET CLIがユーザー領域に書き込めない状態がトリガーになっているケースが多いです。
- まずは
dotnet workload repair→dotnet workload updateを通す dotnet workload listでmauiが見えることを確認する- 必要なら
dotnet workload install mauiで入れ直す - 並行して
~/.dotnetの所有者・権限を確認し、ズレがあれば修正する
この順で潰すと、VS Code側の設定に手を入れる前に、かなりの確率で“デバッグが動くところまで”戻せます。逆に、ここを飛ばして拡張機能やlaunch.jsonだけをいじると、根本原因が残り続けて時間を溶かしがちです。まずはCLI(dotnet)が気持ちよく通る状態を作る、が正攻法です。

コメント