Решение проблем
Дерево диагностики ActionPulse: событие не появилось, 401 и 403, отказ по origin, зависшее согласие, блокировка политикой безопасности, несовпадение контрольной суммы, отклонение реестром и дубли событий.
На этой странице
- С чего начать
- Событие не отправляется
- Скрипт не загрузился
- Скрипт загрузился, но не инициализировался
- Согласие остаётся в ожидании
- 401 — ключ не принят
- 403 — запрет по origin или правам
- credential_origin_forbidden
- credential_scope_forbidden
- 402 — нет действующей подписки
- 413 и 422 — тело запроса
- 429 — превышен лимит
- 202, но события не видно
- credential_event_forbidden
- invalid_event
- missing_actor и invalid_actor
- invalid_event_id
- too_many_props, prop_key_too_long, prop_value_too_large
- schema_violation
- Событие пришло дважды
- Ошибка проверки контрольной суммы
- Записи сессий не работают, остальное работает
- Автосбор не работает
- Ошибка при серверной отрисовке
- Если ничего не помогло
Начните отсюда: почти всякая проблема видна в ответе сервера или в консоли браузера, а не «где-то в обработке».
С чего начать
- Откройте вкладку «Сеть» в инструментах разработчика и найдите запрос на
/v1/track. - Посмотрите код ответа. Дальше идите по нужному разделу.
| Что видно | Куда смотреть |
|---|---|
| Запроса нет вовсе | Событие не отправляется |
401 |
401 — ключ не принят |
403 |
403 — запрет по origin или правам |
402 |
402 — нет действующей подписки |
413 или 422 |
413 и 422 — тело запроса |
429 |
429 — превышен лимит |
202, но событий нет |
202, но события не видно |
Событие не отправляется
Симптом. В сетевой панели нет запросов на /v1/track, window.pp не
определён либо определён, но ничего не происходит.
Скрипт не загрузился
Проверьте, есть ли в сетевой панели сам файл трекера и с каким кодом он пришёл.
| Причина | Как проверить | Что делать |
|---|---|---|
| Опечатка в адресе | код ответа 404 |
сверьте путь с экраном установки |
| Блокировка политикой безопасности | в консоли сообщение про Content Security Policy |
добавьте origin скрипта в script-src |
| Блокировщик рекламы | запрос отменён без ответа | проверьте в другом браузере или профиле |
| Несовпадение контрольной суммы | в консоли сообщение про integrity |
см. ниже |
Скрипт загрузился, но не инициализировался
Самая коварная причина: указаны и data-token, и data-key с разными
значениями. Трекер в этом случае молча ничего не делает — без ошибки в
консоли. Оставьте один атрибут.
Другие варианты: значение токена обрезано при копировании, вместо браузерного токена подставлен серверный ключ, значение подставляется шаблонизатором и осталось незаполненным.
Браузерный токен — это pp_bt_ плюс 8 символов, подчёркивание
и ещё 32 символа. Значение любой другой формы трекер не примет.
Согласие остаётся в ожидании
Если стоит data-consent="required", до вызова pp.setConsent('granted')
запросов не будет — это правильное поведение.
pp.getConsent(); // 'pending' — сбор ещё не начат
Частая ошибка: CMP вызывает setConsent только по клику на баннере, а на
следующих страницах ничего не вызывает. Состояние согласия хранится в памяти
страницы и не переживает переход — CMP должен сообщать решение на каждой
загрузке. Подробности — в руководстве по согласию.
401 — ключ не принят
Ответ.
{ "error": { "code": "unauthorized", "message": "invalid credential", "details": {} } }
Сообщение намеренно одинаковое для всех причин, чтобы по нему нельзя было подбирать ключи.
| Причина | Как проверить |
|---|---|
| Ключ отозван или заменён | список ключей проекта в настройках |
| Браузерный токен истёк | срок по умолчанию — 90 дней с выпуска |
| Значение обрезано или содержит пробел | сравните длину: 8 символов префикса и 32 секрета |
| Заголовок собран неверно | должно быть ровно Authorization: Bearer <ключ> |
| Ключ передан в адресе запроса | так работают только совместимые ключи pp_wk_… |
Некорректно оформленный заголовок Authorization не даёт «провалиться» на
другой способ передачи ключа — запрос сразу получит 401.
403 — запрет по origin или правам
credential_origin_forbidden
{ "error": { "code": "credential_origin_forbidden",
"message": "browser credential origin is not allowed", "details": {} } }
Origin страницы не совпал со списком, заданным при выпуске токена.
| Проверьте | Пример |
|---|---|
| Схема | http://example.com и https://example.com — разные origin |
| Поддомен | example.com не покрывает www.example.com |
| Порт | https://example.com:8443 нужно указывать отдельно |
| Маски | https://*.example.com не работает — только точные адреса |
| Пустой список | токен без origin отклоняется всегда |
Список origin после выпуска токена не редактируется. Чтобы добавить домен, выпустите новый токен со всеми нужными адресами и замените значение в теге.
credential_scope_forbidden
{ "error": { "code": "credential_scope_forbidden",
"message": "credential is not allowed for this endpoint", "details": {} } }
Ключ не того типа. Браузерный токен не может связывать идентификаторы через
/v1/alias, серверный ключ не может отправлять записи сессий.
402 — нет действующей подписки
Приём остановлен по биллингу, а не по технической причине.
| Код | Что означает |
|---|---|
trial_expired |
пробный период закончился |
subscription_required |
нет действующей подписки |
В details приходит ссылка на биллинг. Пока подписка не восстановлена, события
не принимаются.
Отдельный случай — 403 с кодом trial_pending_review: аккаунт на проверке.
413 и 422 — тело запроса
| Код ответа | Сообщение | Что делать |
|---|---|---|
413 |
payload exceeds 256KB |
разбейте батч или уменьшите свойства |
422 |
batch is empty |
не отправляйте пустой массив |
422 |
batch exceeds 500 items |
не больше 500 элементов в запросе |
422 |
invalid JSON body |
см. ниже |
invalid JSON body — это не только синтаксическая ошибка. Разбор строгий:
неизвестное поле в любом месте структуры отклоняет весь запрос. Проверьте,
что вы не добавили своих полей рядом с batch, и что внутри элемента только
разрешённые имена: event_id, event, anon_id, user_id, session_id,
time, props, url, referrer, schema_version.
Свои данные кладите в props, а не рядом с ним.
429 — превышен лимит
{ "error": { "code": "rate_limited", "message": "ingest rate limit exceeded", "details": {} } }
В ответе есть заголовок Retry-After в секундах — используйте его, а не
фиксированную паузу. Повторяйте с экспоненциальной задержкой.
Отдельный случай — 429 с кодом trial_quota_exceeded: исчерпан лимит событий
пробного периода. Заголовка Retry-After в этом случае нет, и повторы не
помогут.
202, но события не видно
202 возвращается и тогда, когда часть батча отклонена. Смотрите
поле rejected:
{ "accepted": 0, "n": 1, "rejected": [{ "i": 0, "code": "credential_event_forbidden" }] }
credential_event_forbidden
Ключ не имеет права отправлять это имя события.
| Ситуация | Решение |
|---|---|
| Своё событие из браузера, имени нет в списке токена | выпустите токен с нужным списком или отправляйте с сервера |
| Бизнес-событие из браузера | payment_succeeded, order_paid, order_created, refund, registered и подобные принимаются только с серверным ключом |
pp.* с серверного ключа |
это пространство принадлежит браузерному сбору |
Только что выпущенный браузерный токен разрешает одно пользовательское событие
— signup_completed. Всё остальное вернётся с этим кодом. См.
события и пользователи.
invalid_event
Имя не подходит под ^[a-z0-9_.]{1,128}$. Заглавные буквы, кириллица,
пробелы, дефисы недопустимы. Order_Created → order_created.
missing_actor и invalid_actor
Нужен хотя бы один из user_id и anon_id. invalid_actor — идентификатор
длиннее 256 символов или содержит нулевой байт.
invalid_event_id
event_id должен быть UUID. Свой формат идентификатора здесь не подойдёт: либо
присылайте UUID, либо не присылайте поле совсем — тогда сервер сгенерирует его
сам, но защита от дублей при повторах работать не будет.
too_many_props, prop_key_too_long, prop_value_too_large
Превышены лимиты свойств: не больше 64 ключей, имя до
64 символов, значение до 8 КБ. Крупные значения —
например, весь ответ API целиком — в свойства класть не нужно.
schema_violation
Проект в строгом режиме проверки, и событие нарушило контракт из реестра. В ответе приходит список нарушений; на экране проверки интеграции видно, какое именно свойство не сошлось.
Типовые причины: свойство поменяло тип (число стало строкой), не хватает обязательного свойства, событие не зарегистрировано.
Пока разметка не устоялась, держите проект в режиме мониторинга: нарушения будут видны, а события продолжат приниматься.
Событие пришло дважды
| Причина | Решение |
|---|---|
Повтор без стабильного event_id |
генерируйте event_id один раз при создании события и переиспользуйте при повторах |
| Одно событие шлют и браузер, и сервер | защита от дублей действует в пределах одного источника — выберите одну сторону |
| Тег подключён дважды | проверьте разметку и тег-менеджер |
Ошибка проверки контрольной суммы
Симптом. В консоли сообщение о том, что ресурс не прошёл проверку
integrity, скрипт не выполняется.
| Причина | Решение |
|---|---|
| Значение взято из чужой установки | возьмите своё из https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/manifest.json |
| Оставлен плейсхолдер | SRI_FROM_MANIFEST — не хеш, его нужно заменить |
Обновили версию, а integrity нет |
версия и сумма меняются одной правкой |
| Файл изменён при раздаче | CDN не должен минифицировать или преобразовывать файл |
Нет crossorigin="anonymous" |
при загрузке с другого домена без него проверка невозможна |
Записи сессий не работают, остальное работает
Классический признак нехватки worker-src blob: в политике безопасности.
Записи используют фоновый поток, остальной сбор — нет, поэтому ломается только
одна возможность.
Проверьте также, что записи включены в настройках проекта: по умолчанию они выключены, и доля записываемых сессий тоже начинается с нуля.
В консоли может появиться запрос несуществующего файла карт исходников с
ответом 404 — это косметика, на работу не влияет.
Автосбор не работает
| Проверьте | Как |
|---|---|
| Согласие получено | pp.getConsent() возвращает granted |
| Область не исключена | нет data-pp-ignore или data-pp-block выше по дереву |
| Автосбор включён в настройках проекта | раздел настроек поведения |
| Дополнительный модуль загрузился | в сетевой панели файл модуля, код ответа 200 |
Если модуль недоступен или его сумма не совпала, соответствующая возможность просто не включается — базовый сбор при этом продолжает работать.
Ошибка при серверной отрисовке
Симптом. Сборка или сервер падает с обращением к window или document.
Точка входа пакета безопасна для импорта в универсальном коде, а вот
инициализация требует браузера и на сервере бросает ошибку намеренно.
Вызывайте её только на клиенте: в компоненте с директивой 'use client', в
плагине с суффиксом .client или под проверкой окружения.
Если ничего не помогло
Соберите перед обращением в поддержку:
- код ответа и тело ответа на
/v1/track(без значения ключа); - префикс ключа — первые символы до второго подчёркивания;
- origin страницы;
- имя события и время попытки в UTC;
- снимок экрана вкладки «Нарушения» на экране проверки интеграции.