Ошибки 1С ODATA
Содержание
- Формат тела ошибки
- HTTP-статусы и их интерпретация
- Коды по группам
- Матрица: семейство эндпоинта × типичные коды
- Decision tree: симптом → код
1. Формат тела ошибки
При HTTP 4XX тело — XML с <m:code> и <m:message>. Json-варианта тела ошибки не существует даже при $format=json в запросе — XML отдаётся вне зависимости от запрошенного формата представления.
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code>9</m:code>
<m:message>Экземпляр сущности "НакладнаяОтгрузки" не найден по переданному ключу.</m:message>
</m:error>| Поле | Содержимое |
|---|---|
<m:code> | внутренний числовой код 1С (0–21); см. ниже по группам |
<m:message> | человекочитаемое сообщение на языке локали сервера (обычно русский) |
При HTTP 5XX структура тела не гарантируется — может быть произвольный текст, HTML страница IIS или что-то ещё. Парсер должен это учитывать: на 5XX не пытаться извлекать <m:code>, ставить fallback на (status, raw_body).
Парсинг. Если используете lxml/xml.etree, не забыть про namespace xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata". Удобный паттерн — namespace map {"m": "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"} и xpath .//m:code, .//m:message.
2. HTTP-статусы и их интерпретация
| HTTP | Значение в 1С |
|---|---|
400 | большинство 4XX-ошибок 1С (парсинг URL, $filter, неверное значение) — конкретика в <m:code> |
401 | не аутентификация, а ограничение доступа к данным (RLS): выборка попала под запрет без allowedOnly=true. Внутренний код 20. |
403 | реальный недостаток прав на ресурс (роль/привилегия отсутствует) — также код 20 |
404 | ресурс/сущность не найдены; обычно сопровождается кодом 8 (тип сущности) или 9 (экземпляр) |
405 | Method Not Allowed — обычно код 19 (метод запрещён в данном контексте) |
409 | Conflict — встречается с кодом 15 (ключ уже занят) |
412 | If-Match не совпал с текущим DataVersion — оптимистическая блокировка |
415 | Unsupported Media Type — неверный Content-Type |
500 | внутренняя ошибка 1С/прикладного решения — тело произвольное |
501 | попытка прочитать тип, который OData не поддерживает (см. reference §17.4.3) |
Важное наблюдение про 401. В 1С это семантически «RLS отрезала строки», а не «логин не прошёл». На клиенте — не пытаться сделать reauth; вместо этого добавить allowedOnly=true или уточнить $filter. Реальный 401 от веб-сервера (неправильный пароль) обычно сопровождается совсем другим телом — без <m:code>.
3. Коды по группам
URL и адресация
Код 1 — Не удалось разобрать строку
Когда: парсер URL/тела упал на синтаксисе.
Причины: незакрытая скобка, неэкранированная одинарная кавычка, лишний &, перекодированные двойным кодированием символы.
Что делать: проверить URL глазами, проверить экранирование одинарных кавычек (''), убедиться что percent-encoding не применён дважды.
Код 2 — Неверный формат запроса
Когда: общая структура запроса не разбирается (несинтаксическая, выше уровня).
Причины: некорректное тело при POST/PATCH, не соответствующее Content-Type; перепутаны json и atom; битый charset.
Что делать: сверить Content-Type с реальным телом; для json — UTF-8 без BOM.
Код 6 — Неверный URL
Когда: путь не соответствует ни одному из шаблонов стандартного интерфейса.
Причины: опечатка в префиксе (Catalogs_Товары вместо Catalog_Товары), лишний сегмент в пути, попытка использовать _Type/_Key суффикс как часть URL.
Что делать: сверить с правилами имени ресурса, вспомнить что имена объектов конфигурации — в русском написании 1С, не транслит.
Код 7 — Не хватает элемента ключа сущности
Когда: GET/PATCH/DELETE одиночной сущности с составным ключом.
Причины: передали только одну часть ключа (например, для записи независимого регистра сведений — Период=... без Валюта_Key=...).
Что делать: передавать все компоненты составного ключа парами Имя=Значение, через запятую.
Код 8 — Тип сущности не найден
Когда: обращение к несуществующему Catalog_X/Document_X/...
Причины: объект не опубликован в составе стандартного интерфейса OData (см. УстановитьСоставСтандартногоИнтерфейсаOData); опечатка в имени; объект переименован в конфигурации.
Что делать: запросить B/ или $metadata — посмотреть, есть ли тип в выдаче. Если нет — конфигурация не публикует его.
Код 9 — Экземпляр сущности не найден
Когда: GET/PATCH/DELETE по конкретному ключу, которого в базе нет.
Причины: объект удалён физически; передан ключ из другой базы; перепутаны Ref_Key и Recorder_Key.
Что делать: убедиться, что guid существует; для регистров — перепроверить, кого передаём в ключ (запись vs набор по регистратору).
Код 18 — В объекте есть свойства с одинаковыми именами
Когда: ошибка инициализации интерфейса при первом обращении к объекту.
Причины: в конфигурации в одном объекте есть, например, реквизит с именем Date и стандартный реквизит Date — коллизия при экспорте в OData.
Что делать: это конфигурационная проблема, решать на стороне 1С (переименовать реквизит).
Свойства и значения
Код 4 — Неверное значение свойства
Когда: POST/PUT/PATCH с телом, в котором значение не разбирается в тип реквизита.
Причины: строка вместо числа, неверный формат Edm.DateTime (нужен "yyyy-mm-ddThh:mm:ss" без таймзоны), null для обязательного поля.
Что делать: сверить с $metadata тип реквизита; для дат — без Z и без +03:00.
Код 5 — Отсутствует обязательное значение свойства
Когда: POST или PUT, в теле нет обязательного поля.
Причины: PUT требует все поля; POST требует обязательные. Часто забывают Date у документа, Period у независимого регистра сведений.
Что делать: прочитать $metadata, выяснить набор Nullable=false; перед PUT — сделать GET и слить с патчем.
Код 10 — Запрошенное свойство не найдено
Когда: $select=..., dot-traversal или ссылка на несуществующее свойство в $filter/$orderby.
Причины: опечатка; стандартный реквизит написан кириллицей в dot-path (должен быть английским — Description, не Наименование); попытка обратиться к табличной части как к скаляру.
Что делать: сверить написание; в dot-traversal стандартные реквизиты только английские.
Код 15 — Сущность с таким ключом уже существует
Когда: POST с явно переданным Ref_Key, и такой ключ уже занят.
Причины: ретрай POST'а без идемпотентного механизма; миграция данных с фиксированными guid'ами.
Что делать: при ретрае — проверить через GET, не создан ли уже; при миграции — использовать 1C_OData-DataLoadMode: true (если объект поддерживает).
Код 16 — Не удалось присвоить свойство
Когда: PATCH/PUT пишет в свойство, которое сервер отказывается обновлять.
Причины: запись в read-only поле (Posted, DataVersion, поля, заполняемые при проведении); нарушение бизнес-логики прикладного решения (заполнить запрещено в текущем состоянии).
Что делать: Posted — через команду /Post, не PATCH; для бизнес-логики 1С — изучить причину на стороне конфигурации, возможно нужен 1C_OData-DataLoadMode: true.
Метод и контекст
Код 13 — Создание строк табличных частей напрямую не поддерживается
Когда: POST B/Document_X_Товары или POST B/InformationRegister_X(<Recorder>) — попытка добавить строку через эндпоинт коллекции строк.
Причина: OData v3 в 1С не реализует прямой POST на табличные части и наборы записей.
Что делать: PATCH родителя (для табличной части) или PATCH набора регистра (для записей) — с полной перезаписью массива. См. endpoints.md §8.3, §8.4.
Код 17 — Объект не поддерживает режим загрузки данных
Когда: заголовок 1C_OData-DataLoadMode: true отправлен в запросе к объекту, который такой режим не разрешает.
Причины: прикладное решение запретило отключение проверок для этого объекта.
Что делать: убрать заголовок и пройти штатные проверки; или решить на стороне конфигурации.
Код 19 — HTTP-метод запрещён в данном контексте
Когда: метод не подходит к семейству эндпоинта. Типичные случаи:
POSTна single-entity (вместо PATCH/PUT).PATCH/PUTна коллекцию (вместо POST для создания).DELETEна коллекцию.POSTна journals (read-only).GET/DELETEна bound-action (это POST-only). Что делать: см. Типы эндпоинтов — какой метод осмыслен у какого семейства.
Параметры запроса
Код 3 — Запрошенный тип представления не поддерживается
Когда: $format=json или Accept: application/json на эндпоинте, который json не отдаёт.
Где всплывает: B/$metadata, B/SelectChanges. На $metadata 1С фактически молча отдаёт XML, но семантически — «формат не поддерживается».
Что делать: не запрашивать json там, где его не существует; парсить XML.
Код 14 — Ошибка разбора опций запроса
Когда: синтаксис в $filter, $orderby, $expand, $select не разбирается.
Причины: неэкранированная одинарная кавычка в литерале, неверный оператор (== вместо eq), неполный путь в $expand (составной реквизит без типа), битый Condition='...' в виртуальной таблице.
Что делать: разобрать выражение глазами; для составных типов — добавить cast(); для Condition= — проверить удвоение одинарных кавычек.
Функции и действия
Код 11 — Метод не найден
Когда: обращение к несуществующей функции/действию на ресурсе.
Причины: SliceLast на справочнике (есть только у регистров); Post на документе, не поддерживающем проведение; неверное имя виртуальной таблицы (SliceLast() — правильно, Срез() — нет).
Что делать: проверить набор функций в $metadata для конкретного ресурса. Имена виртуальных таблиц — английские (см. endpoints.md §11).
Код 12 — Отсутствует обязательный аргумент метода
Когда: вызов виртуальной таблицы без обязательного параметра.
Причины: Turnovers() без StartPeriod/EndPeriod; SliceLast(Condition=...) без Period (если регистр требует); Balance() регистра бухгалтерии без AccountCondition.
Что делать: сверить набор параметров с $metadata (там описаны функции с сигнатурами).
Код 21 — Вызов нереализованной функции / неверные аргументы / нереализованная лямбда
Когда: функция распознана как имя, но не реализована, либо параметры лямбды неверны. Типичные случаи:
tolower(),toupper(),trim(),length(),indexof(),replace()— не реализованы.floor(),ceiling(),years(),days(),hours(),seconds()— не реализованы.$filter=Товары/Цена gt 10000(фильтр коллекции без лямбды). Что делать: для строк —like,startswith,endswith,substring,substringof; для коллекций —any(d: d/Цена gt 10000). См. pitfalls §2.
Права доступа
Код 20 — Нет прав на действие, либо выборка попала под ограничение без allowedOnly
Когда: есть пересечение между запросом и ограничениями доступа к данным (RLS) — без явного allowedOnly=true.
HTTP-статус: обычно 401 (важно: это не ошибка аутентификации); может быть 403 при отсутствии роли вообще.
Что делать:
- На GET коллекции — добавить
?allowedOnly=true. - На POST/PATCH/DELETE —
allowedOnlyне помогает; нужно либо иметь права на конкретный объект, либо предварительно отфильтровать выборку. - Если действие совсем недоступно (роль не выдана) — решать на стороне 1С.
См. pitfalls §6.
Возможность отсутствует
Код 0 — Возможность не поддерживается
Когда: общая «затычка» — для функций OData, которые 1С не реализовала вообще.
Примеры: $batch, deep insert (создание родителя с табличной частью одним POST с навигационными ссылками), $crossjoin, любые расширения, появившиеся после v3.
Что делать: разбить операцию на штатные шаги; в части $batch — заменить на последовательность отдельных HTTP-запросов.
4. Матрица: семейство эндпоинта × типичные коды
| Код | service-root | entity-set GET | entity-set POST | single-entity GET | single-entity PATCH/PUT | single-entity DELETE | bound-function | bound-action | service-operation |
|---|---|---|---|---|---|---|---|---|---|
| 0 | — | редко | редко | — | редко | — | — | — | — |
| 1 | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 2 | — | — | ✓ | — | ✓ | — | — | — | — |
| 3 | ✓ | — | — | — | — | — | — | — | ✓ (SelectChanges) |
| 4 | — | — | ✓ | — | ✓ | — | — | — | — |
| 5 | — | — | ✓ | — | ✓ (PUT) | — | — | — | — |
| 6 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 7 | — | — | — | ✓ | ✓ | ✓ | — | ✓ | — |
| 8 | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (узел) |
| 9 | — | — | — | ✓ | ✓ | ✓ | — | ✓ | ✓ (узел) |
| 10 | — | ✓ | — | ✓ | — | — | ✓ | — | — |
| 11 | — | — | — | — | — | — | ✓ | ✓ | — |
| 12 | — | — | — | — | — | — | ✓ | — | ✓ |
| 13 | — | — | ✓ (на _<TP>) | — | — | — | — | — | — |
| 14 | — | ✓ | — | — | — | — | ✓ (Condition=) | — | ✓ (params) |
| 15 | — | — | ✓ | — | — | — | — | — | — |
| 16 | — | — | ✓ | — | ✓ | — | — | — | — |
| 17 | — | — | ✓ | — | ✓ | — | — | — | — |
| 18 | — | редко | редко | редко | редко | — | — | — | — |
| 19 | — | ✓ (PUT/PATCH/DELETE на коллекцию) | ✓ (POST на single) | — | ✓ | ✓ | — | ✓ (GET/DELETE) | ✓ (GET) |
| 20 | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 21 | — | ✓ ($filter) | — | — | — | — | ✓ | — | — |
5. Decision tree: симптом → код
4XX без <m:code> в теле
- Веб-сервер обрезал/не дошло до 1С (проверь URL, перенаправления, статус ответа).
- Это реальный 401 от IIS/Apache (не RLS — а провал аутентификации).
4XX с <m:code> в теле
- Сначала смотри код, потом
<m:message>. Сообщения 1С информативны на русском. - Если код входит в группу URL/адресации (1, 2, 6, 7, 8, 9) — проблема в формировании запроса.
- Если код в группе значений (4, 5, 10, 15, 16) — проблема в теле POST/PATCH/PUT.
- Если код в группе функций (11, 12, 21) — проблема в виртуальной таблице или
$filter.
HTTP 412
If-Matchустарел → перечитать сущность, повторить с новымDataVersion.
HTTP 501
- Попытка прочитать тип, который OData не поддерживает (некоторые объекты
ХранилищеЗначения, скрытые типы). Подробнее: reference §17.4.3.
HTTP 5XX
- Парсер
<m:code>не применять — тело произвольное. - Логировать
(status, headers, raw_body[:8KB]); не пытаться восстановиться, делать retry с экспоненциальной паузой.
См. также
- endpoints.md §3 — компактная таблица всех кодов.
- Подводные камни и рецепты — как избежать большинства из этих ошибок.
- Типы эндпоинтов — какое семейство какие коды генерирует.