Что делать, если 1С пишет «Ошибка формата потока»

· 10 мин

Содержание

Сообщение Ошибка формата потока означает одно: платформа получила на вход набор байтов, который попыталась прочитать как сериализованное значение, но структура не совпала с ожидаемой. Поток — это любой упорядоченный массив данных: кэш клиента, строка из хранилища настроек, файл .dt, внешняя обработка, двоичные данные в реквизите.

У рядового пользователя причина почти всегда локальная — повреждённый кэш на его компьютере. Лечится за минуту: запуск с параметром /ClearCache или удаление папки кэша базы. У разработчика причина глубже — десериализация таблицы значений, хранилища или данных, записанных другой версией платформы.

Ниже — как по симптому отличить одно от другого, где искать источник в коде и как не повредить рабочую базу по дороге.

Что за ошибка и какие потоки её вызывают

Текст ошибки не говорит, какой именно поток повреждён, — отсюда и сложность. Но набор источников ограничен, и каждый даёт свой характерный сценарий.

  • 🗂️ Кэш клиента. Повреждается при аварийном завершении сеанса, обрыве связи с сервером, переполнении диска. Ошибка вылезает при запуске или открытии конкретной формы.
  • 💾 Хранилище настроек. Платформа читает сохранённые настройки формы или отчёта и спотыкается на повреждённой записи. Форма не открывается у одного пользователя, у остальных всё в порядке.
  • 📦 Файл .dt. Выгрузка оборвалась или файл скопировали по ненадёжному каналу. При загрузке — ошибка формата потока.
  • 🧩 Внешняя обработка или отчёт. Файл .epf/.erf сохранён в более новой версии платформы, чем та, что пытается его открыть.
  • 🔢 Значение в реквизите или регистре. В базе лежит строка, полученная через ЗначениеВСтрокуВнутр, и её читают платформой, которая эту структуру уже не понимает.

Общий знаменатель: байты есть, но их формат не тот, что ждёт читающая сторона. Дальше идём от самого частого к самому редкому.

Быстрое решение: очистка кэша клиента

Если ошибка появилась «вдруг» и ровно у одного-двух пользователей, начинайте отсюда. В 80% бытовых случаев этого достаточно, и код трогать не нужно.

Способ 1 — параметр запуска. В окне запуска 1С выделите базу, нажмите Изменить и в поле дополнительных параметров запуска впишите:

/ClearCache

Запустите базу один раз с этим параметром — платформа пересоберёт кэш заново. После успешного входа параметр можно убрать.

Способ 2 — удаление папки кэша вручную. Закройте все сеансы 1С на этом компьютере и удалите каталог кэша базы. Он лежит здесь:

%LOCALAPPDATA%\1C\1cv8\

Внутри — подпапки с длинными именами из цифр и букв (идентификаторы баз). Если базу жалко искать среди них, удалите все подпапки: платформа восстановит кэш при следующем запуске каждой базы.

Перед удалением проверьте, что 1С полностью закрыта — в диспетчере задач не должно остаться процесса 1cv8.exe. Иначе папка окажется занята.

При работе через веб-клиент почистите кэш браузера для адреса публикации — там хранится аналог клиентского кэша.

Очистка кэша сбрасывает локальные настройки форм этого пользователя (ширины колонок, отборы списков). Данные в базе не затрагиваются, но пользователя стоит предупредить.

Если после чистки кэша ошибка осталась и повторяется у всех — причина не в кэше, идём дальше.

Где искать источник: отладчик и журнал регистрации

Когда ошибка воспроизводится при конкретном действии (провести документ , открыть отчёт, выполнить обработку), нужно поймать строку кода, на которой она возникает.

  1. Откройте журнал: Администрирование → Журнал регистрации. Отфильтруйте по уровню Ошибка и по времени сбоя — в тексте события часто виден модуль и процедура.
  2. Для клиентского кода включите отладку: в Конфигураторе меню Отладка → Начать отладку, поставьте точку останова в подозрительной процедуре.
  3. Для серверного кода отладку включают в свойствах информационной базы (разрешение на отладку), затем подключаются к серверному сеансу через Отладка → Подключение.

Включение отладки на сервере и переподключение к сеансам делайте в согласованное окно: у активных пользователей сеанс может прерваться. На проде — вне рабочего времени.

Чтобы отладчик остановился ровно на ошибке, оберните подозрительный вызов в попытку и поставьте точку останова в блоке Исключение:

Попытка
    Значение = ЗначениеИзСтрокиВнутр(СтрокаХранилища);
Исключение
    Сообщить("Не разобрался поток: " + ОписаниеОшибки());
КонецПопытки;

В момент исключения в стеке вызовов видно, откуда пришла СтрокаХранилища, — это и есть повреждённый или несовместимый поток. Для фоновых заданий и серверных процессов подробности пишутся в технологический журнал (logcfg.xml), если он настроен.

Сериализация таблиц значений и хранилищ

Самый частый «кодовый» источник ошибки — чтение таблицы значений или другого объекта из строки, в которую его когда-то упаковали.

Функции ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр используют внутренний бинарный формат платформы. Он не гарантирует совместимость между разными версиями: строку, записанную на 8.3.21, не всегда корректно читает 8.3.10. Если такие строки хранятся в реквизитах или регистрах сведений, после обновления платформы часть из них перестаёт читаться.

Что с этим делать:

  • 🔁 Перезаписать значения. Разово пройдите по данным той версией, что ещё их читает, и сохраните заново — лучше через СериализаторXDTO или в формате, не завязанном на внутреннее представление.
  • 🧪 Защитить чтение. Любую десериализацию из внешнего источника заворачивайте в Попытка/Исключение и предусматривайте значение по умолчанию, чтобы одна битая запись не роняла всю обработку.
  • 📋 Проверить источник строки. Убедитесь, что в реквизит действительно пишется результат ЗначениеВСтрокуВнутр, а не, например, усечённая строка или данные из внешней системы в чужой кодировке.

Отдельный подвид — хранилище настроек. Если форма перестала открываться с ошибкой формата потока у одного пользователя, повреждена его сохранённая настройка. Удалите её: в хранилище общих настроек найдите ключ этой формы по имени объекта и очистите сохранённое значение для проблемного пользователя. Форма откроется с настройками по умолчанию.

Если не уверены, какой именно ключ чистить, самый безопасный приём — удалить настройки формы только у пострадавшего пользователя, а не очищать хранилище целиком.

Правило на будущее: для долгоживущих данных в базе не опирайтесь на ЗначениеВСтрокуВнутр. Этот формат удобен для временной передачи значения между сеансами, но не предназначен для хранения годами через смену версий платформы. Для таких случаев сериализуйте в XML или JSON — их формат стабилен и переносим.

Чтение двоичных и внешних файлов

Если ошибка возникает в момент, когда код читает файл с диска или двоичные данные из реквизита, проблема обычно не в платформе, а в несоответствии содержимого ожидаемому формату.

Типичный сценарий: код вызывает ЗначениеИзФайла и ждёт на входе файл с сериализованным значением, а ему подсунули файл другого типа или повреждённый. Платформа начинает разбирать поток байтов по правилам ожидаемого формата и спотыкается на первом же несоответствии.

Что проверить:

  • 📎 Тип и источник файла. Убедитесь, что читаете именно тот файл, который записывали, а не одноимённый из другой выгрузки. Сверьте размер и, если возможно, сигнатуру (первые байты) с эталоном.
  • 🔐 Целостность двоичных данных. Если ДвоичныеДанные берутся из реквизита, проверьте, что запись не обрывалась: при аварийном завершении транзакции в поле могла попасть только часть данных.
  • 🧷 Кодировку и упаковку. Файл, пришедший из внешней системы, мог быть перекодирован или распакован не до конца. Читайте его тем же способом, которым он формировался.

Чтение внешних данных всегда оборачивайте в защиту — тогда битый файл даст понятное сообщение, а не аварийный останов посреди пакетной обработки:

Попытка
    Данные = ЗначениеИзФайла(ПутьКФайлу);
Исключение
    ЗаписьЖурналаРегистрации("Импорт", УровеньЖурналаРегистрации.Ошибка, , ,
        "Файл не прочитан: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Ошибка при выгрузке и загрузке .dt

Загрузка информационной базы из файла .dt падает с ошибкой формата потока в двух типовых ситуациях.

Файл повреждён при передаче. .dt скопировали через нестабильную сеть, облако с ограничением размера или флешку с ошибками. Сравните размер исходного и полученного файла — они должны совпадать до байта. Если нет — перекопируйте, лучше в архиве с проверкой контрольной суммы.

Выгрузка оборвалась. Процесс Выгрузить информационную базу прервали или на диске кончилось место. Такой .dt неполон. Решение — выгрузить заново, проследив, что операция дошла до конца и места на диске хватает с запасом.

Путь к операции в Конфигураторе: Администрирование → Выгрузить информационную базу и, соответственно, Загрузить информационную базу.

Загрузка .dt полностью замещает содержимое базы и требует монопольного доступа — все пользователи должны выйти. Делайте это только в приёмник или в проверенную копию, а не поверх рабочей базы без резервной копии.

Если .dt принципиально не читается ни на одной машине, он битый безвозвратно — восстанавливайте из другой резервной копии или из .dt, снятого ранее. Пересоздавать базу «с нуля» ради одного файла не нужно.

Внешние обработки и отчёты из другой версии платформы

Внешняя обработка .epf или отчёт .erf — это тоже сериализованный поток. Файл, сохранённый в более новой версии платформы, не всегда открывается в старой: структура формата меняется между релизами.

Признак именно этой причины: обработка открывается на одной машине и падает с ошибкой формата потока на другой, где платформа заметно старее.

Порядок проверки:

  1. Сравните номера платформы на обеих машинах: Справка → О программе. Номер на машине-читателе должен быть не ниже, чем на той, где файл сохранён.
  2. Если нужна работа на старой платформе — откройте и пересохраните обработку в той версии, которая есть у всех пользователей.
  3. Храните исходники обработок (внешний файл в репозитории или в справочнике дополнительных обработок), чтобы при расхождении версий пересобрать файл, а не вытаскивать его из чьего-то кэша.
Диагностика: выберите симптом

Версия платформы и режим совместимости

Когда ошибка массовая и началась сразу после обновления, причина чаще не в данных, а в платформе.

  • 🔄 Разнобой версий на клиентах. После обновления сервера часть компьютеров осталась на старом клиенте. Платформа клиента должна быть не ниже платформы сервера. Обновите клиентов до той же версии.
  • 🧱 Режим совместимости конфигурации. В свойствах конфигурации задан режим совместимости с конкретной версией. Если его двигали вместе с обновлением, поведение сериализации могло измениться — проверьте, что режим соответствует реально используемой платформе.
  • 🩹 Битый дистрибутив платформы. Редко, но установочный пакет скачивается с повреждением. Переустановите платформу из заново загруженного дистрибутива.

Правило простое: сравнивайте версии по номеру и держите клиент не ниже сервера. Формулировки «старее/новее» здесь только путают — ориентируйтесь на числа вида 8.3.21.xxxx.

Чек-лист, чтобы пройти причины по порядку и не перескакивать:

Разбор ошибки формата потока по шагам
Выполнено: 0 / 6

Частые вопросы

Можно ли потерять данные при очистке кэша?
Нет. Кэш — это локальная копия служебных данных на компьютере пользователя. Сбрасываются только его личные настройки форм (отборы, ширины колонок). Содержимое базы не затрагивается.
Почему ошибка появилась после обновления платформы?
Внутренний формат сериализации может меняться между версиями. Строки, записанные через ЗначениеВСтрокуВнутр старой платформой, новая иногда не читает. Плюс клиенты, оставшиеся на прошлой версии, конфликтуют с обновлённым сервером.
Как понять, повреждён `.dt` или проблема в самой базе-источнике?
Сверьте размер выгруженного файла с тем, что получили на другой машине, — при неполной передаче он меньше. Если размеры совпадают, но файл не грузится, выгрузите .dt заново на источнике: возможно, оборвалась сама выгрузка.
Обработка открывается у меня, но не у коллеги — почему?
Скорее всего, у вас разные версии платформы. Файл, сохранённый в более новой, не открывается в старой. Сравните номера в Справка → О программе и пересохраните обработку в общей версии.
Как защитить код от этой ошибки?
Любое чтение значения из строки или внешнего файла оборачивайте в Попытка/Исключение и задавайте значение по умолчанию. Тогда одна повреждённая запись не остановит всю обработку, а в журнал попадёт понятное сообщение.