# よくあるエラーと対処

> 症状やエラーコード（402・409・451 など）から原因と手当てを引く。サイトを作る人と、管理画面を使うお店の人の両方で起きるもの。

URL: https://siteon.dev/ja/docs/troubleshooting

Siteon は、AI で作ったサイトのためのインフラです。AI や手で作った静的サイト（HTML）に、ホスティング・お客さん（お店の人）が直せる CMS・お問い合わせフォーム・アクセス解析・AI エージェントからの操作（CLI・MCP）を足し、そのまま納品できる状態にします。

## 値が入らない（HTML の文言のまま）

1. **少し待つ。** Siteon のホスティングでは 15 秒以内、中継と `data-embed` では公開 JSON が 60 秒キャッシュされるので最長 1 分です
2. **中継の環境変数を確かめる。** `CMS_SITE` と `CMS_ORIGIN` のどちらかが無いと、中継は何もしません
3. **GET で確かめる。** `curl -sD - -o /dev/null https://example.com/ | grep -i sitekit` で `x-sitekit-rendered: 1` が出れば中継は効いています。`curl -I`（HEAD）では付かないので、効いていないと誤解しないこと
4. **キーの綴りを確かめる。** `data-cms="hours.days"` は schema.json の `groups[].key` と `fields[].key` の組み合わせです
5. **一覧が空なら公開状態を確かめる。** 下書きの記事は載りません

## 一部の表示が崩れる・閉じタグが余る

印を付けた要素の中に、同じタグ名の要素が入っています。`<div data-cms="x"><div>…</div></div>` は壊れます。中を `<span>` など別のタグにします。

## 属性が付かない

- `data-cms-attr` を1つの要素に2つ書いていませんか（`href:url data-color:color`）。2つ書くとどちらも付きません。要素を分けます
- タグ名・属性名が大文字だと無視されます
- URL を入れる属性に `javascript:` などで始まる値は入りません

## お知らせの欄が空のまま（「まだありません」も出ない）

`data-cms-filter` で0件になると、行も `data-cms-empty` も出ません。`data-cms-empty` が見るのは一覧そのものが空かどうかです。タグページでは、中継が絞り込んだ一覧を使います（[直せる箇所の印](https://siteon.dev/ja/docs/cms#タグ)）。

## 記事ページの `<title>` や OGP がサイト共通の値になる・`<title>` が2つ出る

`<head>` にも `<template data-cms-entry="news">` を置き、その中に `<title>` や `<meta>` を書きます。静的な `<title>` には `data-cms-fallback="news"` を付けます（[記事ごとのページ](https://siteon.dev/ja/docs/cms#記事ごとのページ)）。

## 文字色やタグの色が付かない

サイトの CSS に `.sk-c-red` などの6色や、`.sk-tag[data-color=…]` を書いていません。属性は出ているのに規則が無い状態です。6色とも最初に書きます。

## 値が二重に入る・一覧の値がおかしい

中継を使うサイトで、script に `data-embed` も付けています。埋め込みは2回実行できません。`data-embed` を外します。

## 「入力内容をご確認ください」と出る（`invalid_request`）

- `required` の項目が空です
- 型の制約を超えています（`text` は 200 文字まで、`email` の形でない など）
- 入力の `name` と schema.json の `fields[].key` を確かめます。誤りのある項目には `aria-invalid="true"` が付きます

## 送信すると `not_found` になる

`data-sitekit-form="…"` の値が schema.json の `forms[].key` と一致していないか、`data-site` のサイト ID が違います。

## 送信ボタンを押すと「送信できませんでした」

- ブラウザの開発者ツールで CORS のエラーが出ている、または応答が `403 origin_not_allowed` なら、そのページのオリジンがサイトの許可ドメインに入っていません（`www` の有無・スキーム・ポートまで完全一致）。この送信は保存されていません。次の節を見てください
- `rate_limited` は同じ接続元から 10 分に 20 件を超えたときです。時間をおけば送れます

## フォームが 403 になる（`origin_not_allowed`）

フォームを置いたページのドメインが、サイトの許可ドメインに入っていません。保存されず、件数にも数えません。

- 管理画面の「設定」→「ドメイン・サイト名」の「フォームを受け付けるドメイン」に、ページのドメイン（コンソールで `location.origin` を実行して出るもの）をそのまま足します。`https://www.example.jp` と `https://example.jp` は別です
- Free のサイトに入れられるのは開発用のドメイン（`*.pages.dev` など）だけです。独自ドメインを入れるには、そのサイトを有料プランにします（`402 upgrade_required`）
- Siteon のホスティングの独自ドメインは、「有効」になれば自動で入ります

手順の詳細は [403 origin_not_allowed の直し方](https://siteon.dev/ja/docs/domains#origin-not-allowed) にあります。

## チェックボックスの値が1つしか届かない

同じ `name` を複数使うと最後の値だけが送られます。キーを分けます（`topic_a`、`topic_b`）。

## 送ったのに届いていない

- **ハニーポット（`_hp`）が埋まっていないか。** 埋まった送信は、画面上は成功に見えても保存されません。`autocomplete="off"` と `tabindex="-1"` を付け、画面の外に置きます
- 管理画面のお問い合わせ一覧にあるなら、保存はされています。届いていないのは通知です（次へ）

## 通知が届かない

お問い合わせの詳細で、通知ごとの成否を見ます。✗ は「連絡が届いていない」であって「お問い合わせが消えた」ではありません。失敗した通知は再送できます。

- **何も記録されていない** — その通知が設定されていません。管理画面の「設定 → 通知 → 各フォーム」で宛先を入れ、オンにします
- **Slack** — チャンネルを消した・アプリを外したときは、Webhook URL を発行し直して入れ直します
- **お礼メールが送られない** — フォームに `type: "email"` の項目があり、値が入っているときだけ送られます
- **schema.json を直したのに宛先が変わらない** — 宛先は schema.json では決めていません。管理画面の「設定 → 通知」が正本です

## GTM でフォーム送信が数えられない

- 管理画面で完了イベント名を変えたのに、GTM のトリガーが古い名前のままになっていませんか
- 中継を使うサイトで `data-gtm` と管理画面の GTM ID の両方を書くと、コンテナが食い違います。`data-gtm` を外します
- GTM のプレビューでフォームを実際に送り、イベント一覧に完了イベントが出るか確かめます

## Webhook が届かない・失敗になる

管理画面の「設定 → 詳細 → Webhook」（または `siteon webhooks list`）で直近の送信結果を見ます。

- **追加できない** — 有料プランのサイトですか（Free では使えません）。URL は `https://` で、ポートの指定・IP アドレスの直書き・`localhost` や `.local` などの内部向けの名前を使っていませんか（[送り先の制限](https://siteon.dev/ja/docs/webhooks#送り先の制限)）
- **リダイレクトしている** — 3xx は追わず失敗になります。転送先の最終の URL を登録し直します
- **時間切れ** — 10秒以内に 2xx を返します。重い処理はキューに積んでから、先に 2xx を返します
- **署名が一致しない** — JSON として読み直す前の本文で計算していますか。秘密は `whsec_` を含めた全体を使います（[署名を確かめる](https://siteon.dev/ja/docs/webhooks#署名を確かめる)）
- **同じ問い合わせが2回届く** — 再送です。`Idempotency-Key` で処理済みの ID を読み飛ばします

## 検索結果にプレビューのページが出る

中継の `CMS_INDEXABLE_HOSTS` に本番のホストだけを書きます（[ホスティングと配信](https://siteon.dev/ja/docs/hosting#検索避けcms_indexable_hosts)）。

## 公開（deploy）が止まる

CLI は、送る前に分かるものは送る前に止めます。`--json` を付けると `error` にコードが入ります。

| コード | 原因 | 手当て |
|---|---|---|
| `dev_publish_paused`（503） | Free のサイトの公開を、運営が一時的に止めている（悪用への対策など） | しばらくしてからやり直す。急ぐときはそのサイトを有料プランにする |
| `billing_inactive`（402） | 支払いが 8 日以上遅れている | 管理画面の請求で支払い方法を確かめる。支払いが確認できれば戻る |
| `deploy_too_large` / `too_many_files`（402） | プランの容量・ファイル数を超える | 不要なファイルを消す（ソースマップや元画像など）か、プランを上げる |
| `file_too_large`（413） | 1 ファイルが 25MiB を超える | 動画は外部に置いて埋め込む。画像は縮める |
| `file_type_not_allowed`（400） | 公開できない種類（`exe` `zip` など） | そのファイルを外す。置ける拡張子は [置けるファイル](https://siteon.dev/ja/docs/hosting#置けるファイル) |
| `reserved_path`（400） | `admin/`・`v1/`・`_sk/` で始まるパス | フォルダの名前を変える |
| `hosting_disabled`（409） | ホスティングを有効にしていない | 先に `siteon hosting enable` |
| `subdomain_required`（409） | サイト ID がサブドメインに使えない（短すぎる・予約語・ブランド名を含む・使用中など。理由は `reason`） | `siteon hosting enable --subdomain 別の名前` |
| `subdomain_taken` / `subdomain_quarantined`（409） | ほかのサイトが使っている、または解放から 90 日以内 | 別の名前にする |
| `subdomain_change_limit`（429） | サブドメインの変更が月 3 回を超えた | 翌月まで待つ |
| `blob_busy`（409） | サーバーが古いファイルを整理している最中 | CLI が自動で待って再試行する。続くなら少し待って実行し直す |
| `deploy_expired` / `blobs_missing`（409） | 送っている途中で時間切れ（24 時間）や中断があった | もう一度 `siteon deploy` |
| `no_previous_deploy` / `deploy_not_retained`（409） | 戻せる版が無い・保持期間を過ぎた | `siteon deploys` で保持している版を確かめる |
| `insufficient_scope`（403） | 鍵に `deploy:write` が無い | 管理画面で権限を付けた鍵を発行し直す |

## 独自ドメインが追加できない・有効にならない （近日）

| コード・状態 | 原因 | 手当て |
|---|---|---|
| `plan_required`（402） | Free のサイト | そのサイトを有料プランにする |
| `quota_hostnames`（402） | プランの枠（Lite 1・Standard 3・Business 10。`www` と www の無い形の組で 1 つ）を使い切った | 使っていないドメインを削除するか、プランを上げる |
| `invalid_hostname`（400） | ドメインの形が違う | `www.example.jp` の形で入れる（`https://`・パスは付けない） |
| `hostname_blocked`（400） | なりすましに使われやすい名前 | 別のドメインを使う |
| `hostname_reserved` / `hostname_in_use`（409） | 別のアカウントが申請中・使用中 / 同じアカウントの別のサイトで使っている | 期限が過ぎてから申請する / そのサイトで削除する |
| `too_many_domain_requests`（429） | 申請は 1 日 5 件まで | 翌日に申請する |
| `hosting_disabled`（409） | ホスティングを有効にしていない | 先に `siteon hosting enable` |
| 「DNS の設定待ち」のまま | CNAME か TXT が入っていない・写し間違い・DNS に反映される前 | 画面のレコードと見比べる。`dig` で確かめる |
| 「失敗」 | 申請から 72 時間以内に確かめられなかった | もう一度追加し、新しい TXT の値に入れ替える |

意味と直し方の全部は [独自ドメインのエラー](https://siteon.dev/ja/docs/domains#domain-errors) と [状態の意味](https://siteon.dev/ja/docs/domains#status) にあります。

## 公開したのに古いまま見える

- **15 秒待ってから**、もう一度読み込みます
- CSS・JS・画像は、ブラウザに残っているものが見えています（CSS・JS は 5 分、画像は 1 日）。ファイル名にハッシュを付けるビルド設定にすると、公開した瞬間から新しいものが届きます
- `siteon deploys` で、公開中（`*`）の版が今回のものか確かめます

## サイトが 404・451・503 になる（ホスティング）

| 応答 | 意味 | 手当て |
|---|---|---|
| `404`「まだ公開されていません」 | ホスティングは有効だが、まだ一度も公開していない | `siteon deploy` |
| `404`（共通のページ） | そのパスのファイルが無い。またはサイトを削除した・アカウントを閉じた | パスとファイル名を確かめる（`/about` は `about.html` か `about/index.html`）。独自の 404 ページは `404.html` を置く |
| `451`「このサイトは現在停止されています」 | 悪用（フィッシングなど）の通報や検査でサイトを停止した | オーナー宛てのメールを確かめる。直してから申し立てる。停止中も `deploy` はできる |
| `503` | Siteon 側の一時的な障害 | 数秒おいて読み込み直す |

`402` で表示が止まることはありません。支払いが遅れても、上限を超えても、配信は続きます。

## 管理画面・API で 402 になる

| コード | 原因 | 手当て |
|---|---|---|
| `upgrade_required` | Free のサイトに本番のドメイン（独自ドメイン）を許可ドメインとして登録しようとした | そのサイトを有料プランにしてから登録する（[Free で入れられるドメイン](https://siteon.dev/ja/docs/domains#allowed-origins)） |
| `quota_exceeded` | 上限に達した（CMS の項目数・写真の容量・AI の回数、Free のフォームの受付 月50件など） | 不要なものを消すか、プランを上げる（[上限に達したとき](https://siteon.dev/ja/docs/plans#上限に達したとき)） |
| `billing_inactive` | 未払いが 8 日を過ぎた、または契約が終わった | 管理画面の請求を確かめる |

フォームの送信が `429 quota_exceeded` になるのは、受付の上限（有料は 120%）に達したときです。保存されません。

## 既存の記事の見え方が変わった

本文の書き方（`**太字**`・`[文字](URL)`・`{color:…}`・素の URL の自動リンク）は、前に書いた記事にも効きます。記号として書いた `**` が太字になるのが一番多い形です。本文を検索して `**` を確かめます。

## 管理画面: ログインできない

ログインを何度も間違えると、しばらくロックされます（ログイン ID と接続元ごとに 10 分に 5 回、ログイン ID ごとに 10 分に 50 回）。**10 分待てば自然に解けます。** 解けないときは、パスワード・ログイン ID の誤りか、担当から外れていないかを確かめます。

## 管理画面: パスワードを変えたら他の端末がログアウトした

仕様です。パスワードを変えると、安全のため他の端末（お店のタブレットなど）はいったんログアウトされます。新しいパスワードで入り直します。

## 管理画面: 動画や写真がアップロードできない

- 受け付ける動画は **MP4（H.264）だけ**です。iPhone の `.mov`（HEVC）や HEIC の写真は、ブラウザで再生・表示できないため受け付けません。拡張子を変えても通りません
- iPhone は「設定 → カメラ → フォーマット → **互換性優先**」にすると、以後の撮影が MP4・JPEG になります（撮影済みのものは変わりません）
- **100MB を超える動画**は受け付けません。YouTube などに上げて、動画ブロックの「外部URL」に貼ります

## 管理画面: リンクを貼っても情報が取れない

リンクカードの「情報を取得」は、相手のページの `og:title` などを読みます。相手のページに OGP が無い・ログインが要る・ボットを弾いている・5秒で応答しない・HTML でない、のどれかなら取れません。異常ではないので、手で書きます。
