Ошибки и частые проблемы
Как читать ошибку
Ошибка ручки:
{ "success": false, "error": "parent_not_found", "message": "parent page \"net-takogo\" from path \"/net-takogo/x/\" does not exist in language en; create it first or pass \"create_missing_parents\": true", "segment": "net-takogo", "created_stubs": [] }
Ошибка до ручки (токен, выбор сайта, тело, маршрут):
{ "code": "missing_token", "message": "an API token is required: Authorization: Bearer <token> or X-OnPress-Key header", "data": { "status": 401 } }
Ветвитесь по коду (error или code) и HTTP-статусу. message — пояснение на английском, в нём обычно сказано, что делать; дополнительные поля несут подробности (languages, candidates, allowed, errors). Полная таблица кодов — коды ошибок.
Предупреждения — не ошибки, но читать их обязательно. Успешный ответ несёт warnings: проигнорированный template, незнакомый ключ frontmatter, сменившийся слаг, неопубликованный родитель, пропущенный вложенный фрейм. Всё, что API сделал не так, как вы просили, приходит сюда, а не отказом.
Частые проблемы
Опубликованная страница отвечает 404
Почти всегда у страницы нет фрейма: на сайте v2 страницу выводит только её фрейм. Проверьте GET /pages/{ref} → page.frame; null — поставьте фрейм (PATCH /pages/{ref} с frame). Другие причины: статус не publish или неопубликован кто-то из родителей (visible: false в ответе публикации); фрейм удалён; адрес другой — возьмите его из link (у языка не по умолчанию есть префикс /en/…).
Правка не видна на сайте
Проверяйте запросом без кук: вошедший в WordPress видит свежую страницу, а посетитель — копию из кэша. API сбрасывает кэш зависимых страниц сам — и когда блок стоит во фрейме страницы, и когда он вставлен прямо в тело через onpress/frame или onpress/repeat; какие страницы задело, видно в ответе записи: rebaked.pages и rebaked.cache.pages. Если правили мимо API, сбросьте кэш адреса — POST /cache/flush {"urls": ["/адрес/"]}. Если у страницы статическая копия, а правили что-то мимо API, — POST /frames/rebake.
Страница задвоилась
Публикация без id ищет существующую страницу по слагу под тем же родителем. Поменяли url на другого родителя — нашлась «не та» ветка, создана вторая страница. Удалите дубль (DELETE /pages/{id}?force=true) и публикуйте с id во frontmatter. Так же дубль появляется при ошибке в слаге или другом lang.
Адрес получился не тот
Слаг берётся из slug, а не из последнего сегмента url: без slug он собирается из заголовка. Пишите slug и url согласованно. Если слаг занят в том же языке под тем же родителем, API добавит суффикс -2 — смотрите slug_changed в ответе.
Меню пустое
Смотрите GET /data/menu.<область>?lang=<язык>: meta.menu_id: 0 — в области на этом языке нет меню (PUT /menus/{ref}/location); meta.invalid_items больше нуля — пункты ведут на удалённые или черновые страницы; same_name_dataset — шапка сайта собрана из набора с тем же коротким именем. Если GET /menus показывает меню в области, а на странице пусто, сравните theme в ответе с темой сайта.
Бинд не подставился
Атрибут data-op-bind написан в двойных кавычках (оборвался) — пишите в одинарных. Токен без значения (page.parent_title у страницы верхнего уровня) или с ошибкой в имени — он в bake.response.unresolved ответа записи фрейма. item.* работает только внутри onpress/repeat.
Повторитель пуст
POST /data/resolve с теми же source, match, page, lang покажет, что он получает. Частые причины: контекстный источник (pages.children, breadcrumbs) без страницы; match по полю, которого нет у элементов; значения сравниваются строками ("3" равно 3, но "3 " — нет); вариант набора на языке страницы пуст, а общего набора нет.
Перевод не связался
422 translation_link_failed с reason: нет lang (lang_required), язык совпадает с оригиналом (same_language), оригинала нет (origin_not_found), у оригинала нет языка (origin_has_no_language — почините POST /pages/language). 409 lang_mismatch — во frontmatter перевода остался id оригинала; выгружайте с ?as=translation_source.
401 на каждом запросе
missing_token — заголовок не дошёл (проверьте Authorization: Bearer $OP_TOKEN и что переменная задана). invalid_token — токен перевыпущен или отозван, или скопирован не целиком (нужны op_ и 64 символа). После 20 неудачных попыток в минуту с адреса — 429 too_many_auth_failures: подождите Retry-After.
403 insufficient_role или 404 site_not_found
Вы не администратор этого сайта. На адресе /site/{siteId}/ чужой и несуществующий сайт отвечают одинаково — 404 site_not_found; на старом адресе с X-OnPress-Blog-Id — 403 insufficient_role. Сетевые операции (POST /sites, домен, удаление) требуют суперадмина.
Запись ушла на главный сайт сети
Запрос на старом адресе без blog_id, заголовка и domain идёт на главный сайт — ответ несёт X-OnPress-Blog-Source: default. Пишите через /site/{siteId}/….
429 too_many_requests
Больше 120 запросов в минуту. Ждите Retry-After секунд; в каждом ответе есть X-RateLimit-Remaining. Массовые операции (заливка десятков картинок, страниц) делайте с паузами.
502 internal_unavailable
Исполнитель на стороне сайта не ответил. Это не ошибка вашего запроса: для записей, которые уже сохранены (фрейм, данные), сохранённое остаётся — повторите вызов позже. Если повторяется на одном сайте, значит исполнитель там не установлен или сайт не отвечает.
Страница на многоязычном сайте уводит сама на себя
У страницы нет языка. POST /pages/language {"missing": true} проставит язык по умолчанию всем таким страницам.
Как искать причину самому
- Прочитайте сущность обратно:
GET /pages/{ref},GET /frames/{ref},GET /data/{name}— API отдаёт то, что лежит на самом деле. - Посмотрите страницу без кук и найдите в исходном коде комментарии с пометкой
op/…: …— каждая вставка, которой нечего вывести, оставляет пояснение. - Проверьте повторители через
POST /data/resolve, фрейм — черезdry_runзагрузки (отчётinserts,sources,frame_refs,live_reasons,warnings). - Сравните
printed.howиstaticс ожиданием:on_requestтам, где ждали статику, — во фрейме есть что-то зависящее от страницы.