{"record":{"id":"b624a92625031414","repo":"Freika/dawarich","slug":"invalid-json-format-in-data-file-message","errorCode":null,"errorMessage":"Invalid JSON format in data file: %{message}","messagePattern":"Invalid JSON format in data file: %(.+?)","errorType":"exception","errorClass":"StandardError","httpStatus":null,"severity":"error","filePath":"app/services/users/import_data/v1_handler.rb","lineNumber":55,"sourceCode":"\n  def process\n    Rails.logger.info \"Processing v1 format archive for user: #{user.email}\"\n\n    json_path = import_directory.join('data.json')\n    raise StandardError, I18n.t('services.users.import_data.v1_handler.data_file_missing') unless File.exist?(json_path)\n\n    initialize_stream_state\n\n    handler = ::JsonStreamHandler.new(self)\n    parser = Oj::Parser.new(:saj, handler: handler)\n\n    File.open(json_path, 'rb') do |io|\n      parser.load(io)\n    end\n\n    finalize_stream_processing\n  rescue Oj::ParseError => e\n    raise StandardError, I18n.t('services.users.import_data.v1_handler.invalid_json', message: e.message)\n  rescue IOError => e\n    raise StandardError, I18n.t('services.users.import_data.v1_handler.read_failed', message: e.message)\n  end\n\n  attr_reader :expected_counts\n\n  # Called by JsonStreamHandler for non-streamed sections\n  def handle_section(key, value)\n    case key\n    when 'counts'\n      @expected_counts = value if value.is_a?(Hash)\n      Rails.logger.info \"Expected entity counts from export: #{@expected_counts}\" if @expected_counts\n    when 'settings'\n      import_settings(value) if value.present?\n    when 'areas'\n      import_areas(value)\n    when 'imports'\n      import_imports(value)","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/services/users/import_data/v1_handler.rb#L37-L73","documentation":"StandardError raised from V1Handler#process's `rescue Oj::ParseError`: data.json was found and opened for streaming SAJ parse, but the JSON document itself is syntactically invalid. The parser's message (character/line position of the violation) is interpolated into 'Invalid JSON format in data file: %{message}', so the exact break location is part of the error.","triggerScenarios":"A data.json truncated by an interrupted export or partial download (large exports are the norm), encoding corruption from re-saving or text-mode transfers, or hand-editing that introduced syntax errors. The file streams via Oj::Parser(:saj), so any stray byte anywhere in the document aborts the import.","commonSituations":"Exports cut off by disk-full or timeout on the source instance, files round-tripped through tools that re-encode bytes, or manual JSON surgery before import.","solutions":["Read the interpolated parser message - it names where parsing failed","Validate locally: jq . data.json (or python -m json.tool) to confirm and locate the corruption","Check archive integrity (unzip -t) and re-download/re-export, then retry the import","If the file is truncated at the tail, re-exporting is the only sound fix - do not hand-append closing brackets for a restore"],"exampleFix":"# before: importing a suspect archive blindly\nUsers::ImportData.new(user, 'maybe-broken-export.zip').import\n\n# after: pre-validate the inner JSON before committing to the import\nOj.load(File.read('tmp/extracted/data.json')) rescue => e\n  # log \"archive corrupt: #{e.message}\" and abort before touching user data","handlingStrategy":"try-catch","validationCode":"# Cheap pre-flight for reasonable sizes: full parse before committing\nbegin\n  Oj.load(File.read(json_path))\nrescue Oj::ParseError => e\n  raise ArgumentError, \"archive data.json corrupt: #{e.message}\"\nend","typeGuard":"def valid_export_json?(path)\n  Oj.load(File.read(path))\n  true\nrescue Oj::ParseError, JSON::ParserError\n  false\nend","tryCatchPattern":"begin\n  Users::ImportData.new(user, archive).import\nrescue StandardError => e\n  if e.message.start_with?('Invalid JSON format in data file')\n    # the suffix is the parser telling you WHERE it broke - surface it\n    notify_user(\"Export file is corrupt (#{e.message}). Re-export and retry.\")\n  else\n    raise\n  end\nend","preventionTips":["unzip -t and jq-validate archives from third parties before import","Transfer exports in binary mode; never re-save JSON through text editors that re-encode","Re-export rather than hand-repairing truncated restore data"],"tags":["import","json","parsing","oj","user-data-restore"],"backgroundTag":"json-parse-error","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}