{"record":{"id":"77f18f7167b42e60","repo":"instructure/canvas-lms","slug":"file-has-no-data","errorCode":null,"errorMessage":"File has no data","messagePattern":"File has no data","errorType":"validation","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"lib/outcomes/csv_importer.rb","lineNumber":79,"sourceCode":"        parse_file(&)\n      rescue CSV::MalformedCSVError\n        raise DataFormatError, I18n.t(\"Invalid CSV File\")\n      rescue ParseError => e\n        raise DataFormatError, e.message\n      rescue ActiveRecord::StatementInvalid => e\n        raise DataFormatError, I18n.t(\"Database error (%{err})\", err: e.message)\n      end\n      status = {\n        errors: file_errors,\n        progress: 100\n      }\n      yield status\n    end\n\n    def parse_file\n      headers = nil\n      total = file_line_count\n      raise ParseError, I18n.t(\"File has no data\") if total < 1\n\n      separator = test_header_i18n\n      rows = CSV.new(@file, col_sep: separator).to_enum\n      rows.with_index(1).each_slice(BATCH_SIZE) do |batch|\n        headers ||= validate_headers(*batch.shift)\n        raise ParseError, I18n.t(\"File has no outcomes data\") if batch.empty?\n\n        errors = parse_batch(headers, batch)\n        status = {\n          errors:,\n          progress: (batch.last[1].to_f / total * 100).floor\n        }\n        yield status\n      end\n    end\n\n    def parse_batch(headers, batch)\n      Account.transaction do","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/outcomes/csv_importer.rb#L61-L97","documentation":"Outcomes::CsvImporter#parse_file first counts the file's lines (file_line_count) and raises ParseError 'File has no data' when the count is below 1, i.e. the uploaded CSV is empty (zero content lines). The importer cannot even attempt header validation without at least one line.","triggerScenarios":"Importing outcomes from a CSV attachment that is completely empty (0 bytes or only a newline stripped by the line counter), so total < 1.","commonSituations":"User selected the wrong/blank file; upload pipeline saved an empty attachment; template file was cleared of all content before upload; export step upstream produced an empty file.","solutions":["Verify the file has content (non-zero size, at least one line) before importing.","Re-export or re-download the outcomes CSV template and populate it with header + data rows.","Add a pre-upload client-side check rejecting empty files with a clear message.","If using an API/import job, confirm the attachment param points to the actual CSV, not an empty temp file."],"exampleFix":"// before\nimporter = Outcomes::CsvImporter.new(file: uploaded)\nimporter.run\n// after\nraise 'CSV file is empty' unless File.size(uploaded.path) > 0\nimporter = Outcomes::CsvImporter.new(file: uploaded)\nimporter.run","handlingStrategy":"validation","validationCode":"raise 'CSV file is empty' if file.nil? || File.size(file.path).zero?","typeGuard":"def non_empty_file?(file)\n  file.respond_to?(:path) && File.exist?(file.path) && File.size(file.path) > 0\nend","tryCatchPattern":"begin\n  importer.run\nrescue Outcomes::CsvImporter::ParseError => e\n  flash[:error] = e.message # 'File has no data'\nend","preventionTips":["Check file size before accepting the upload.","Guide users to the populated outcomes template.","Confirm attachment params point at real files, not empty temp files."],"tags":["csv","import","outcomes","empty-file"],"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"}