{"record":{"id":"2dcb0baf689e5e82","repo":"instructure/canvas-lms","slug":"empty-file","errorCode":null,"errorMessage":"Empty file","messagePattern":"Empty file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/sis/csv/import_refactored.rb","lineNumber":292,"sourceCode":"          csv ||= { file: parallel_importer.attachment.display_name }\n          fail_with_error!(e, csv:)\n        end\n      ensure\n        if !(@run_immediately || ensure_later) &&\n           is_last_parallel_importer_of_type?(parallel_importer) &&\n           !should_stop_import?\n          queue_next_importer_set\n        end\n      end\n\n      def try_importing_segment(input_csv, parallel_importer, importer_object, skip_progress: false)\n        csv = input_csv || begin\n          att = parallel_importer.attachment\n          file = att.open(integrity_check: true)\n          { fullpath: file.path, file: att.display_name }\n        end\n        parallel_importer.start\n        raise \"Empty file\" if File.stat(csv[:fullpath]).size == 0\n\n        count = importer_object.process(csv, parallel_importer.index, parallel_importer.batch_size)\n        parallel_importer.complete(rows_processed: count)\n        # just update progress on completion - the parallel jobs should be short enough\n        update_progress unless skip_progress\n      ensure\n        file&.close\n      end\n\n      def fail_with_error!(e, csv: nil)\n        return @batch if @batch.workflow_state == \"aborted\"\n\n        message = \"Importing CSV for account: \" \\\n                  \"#{@root_account.id} (#{@root_account.name}) sis_batch_id: #{@batch.id}: #{e}\"\n        err_id = Canvas::Errors.capture(e, {\n                                          type: :sis_import,\n                                          message:,\n                                          during_tests: false","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/csv/import_refactored.rb#L274-L310","documentation":"During SIS CSV parallel import, try_importing_segment opens the parallel importer's attachment and stats the file before processing. A zero-byte file means there is no CSV data to process, so the segment is rejected with 'Empty file' before importer_object.process runs.","triggerScenarios":"An SIS batch was submitted where one of the split parallel-import CSV attachments is 0 bytes — e.g. the upload was truncated, an empty file was attached for a data type, or the SIS integration generated a header-less/empty export for that segment.","commonSituations":"Upstream SIS export jobs producing empty files on nights with no data changes; users uploading placeholder/empty CSVs via the SIS import UI; SFTP drops with partial files.","solutions":["Check which CSV attachment is empty and regenerate/re-upload it with actual data","Fix the upstream export to skip (not emit) data types with no rows","Add a pre-flight size check on the SIS zip contents before submitting the batch","Ensure the upload completed (compare byte sizes/checksums against source) before enqueueing"],"exampleFix":"// before\nSisBatch.submit_with_files(files: [empty_csv])\n// after\nnon_empty = files.select { |f| File.size(f) > 0 }\nraise 'no CSV data' if non_empty.empty?\nSisBatch.submit_with_files(files: non_empty)","handlingStrategy":"validation","validationCode":"raise 'empty SIS csv' unless parallel_importer.attachment && parallel_importer.attachment.size > 0","typeGuard":null,"tryCatchPattern":"begin\n  batch.run_parallel_importers\nrescue RuntimeError => e\n  raise unless e.message == 'Empty file'\n  batch.mark_errored('a SIS CSV segment was empty')\nend","preventionTips":["Reject zero-byte files at SIS upload time","Make upstream exports omit empty data types","Verify file sizes/checksums after SFTP transfer"],"tags":["sis","csv","import"],"backgroundTag":"empty-required-field","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}