{"record":{"id":"e79df189c27bb058","repo":"instructure/canvas-lms","slug":"invalid-fields-fields","errorCode":null,"errorMessage":"Invalid fields: %{fields}","messagePattern":"Invalid fields: %(.+?)","errorType":"validation","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"lib/outcomes/csv_importer.rb","lineNumber":149,"sourceCode":"      valid = (encoded || \"\").valid_encoding?\n      raise ParseError, I18n.t(\"Not a valid utf-8 string: %{string}\", string: str.inspect) unless valid\n\n      encoded\n    end\n\n    def validate_headers(row, _index)\n      main_columns_end = row.find_index(\"ratings\") || row.length\n      headers = row.slice(0, main_columns_end).map(&:to_sym)\n\n      after_ratings = row[(main_columns_end + 1)..] || []\n      after_ratings = after_ratings.compact_blank.map(&:to_s)\n      raise ParseError, I18n.t(\"Invalid fields after ratings: %{fields}\", fields: after_ratings.inspect) unless after_ratings.empty?\n\n      missing = (REQUIRED_FIELDS - headers).map(&:to_s)\n      raise ParseError, I18n.t(\"Missing required fields: %{fields}\", fields: missing.inspect) unless missing.empty?\n\n      invalid = (headers - OPTIONAL_FIELDS - REQUIRED_FIELDS).map(&:to_s)\n      raise ParseError, I18n.t(\"Invalid fields: %{fields}\", fields: invalid.inspect) unless invalid.empty?\n\n      headers\n    end\n\n    def import_row(headers, row)\n      simple = headers.zip(row).to_h\n      ratings = row[headers.length..]\n\n      object = simple.to_h\n      object[:ratings] = parse_ratings(ratings)\n      object[:learning_outcome_group_id] = @import[:learning_outcome_group_id]\n      if object[:mastery_points].present?\n        object[:mastery_points] = strict_parse_float(object[:mastery_points], I18n.t(\"mastery points\"))\n      end\n      if object[:friendly_description].present? && object[:friendly_description].length > 255\n        raise InvalidDataError, I18n.t(\"Friendly description is too long (maximum is 255 characters)\")\n      end\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/outcomes/csv_importer.rb#L131-L167","documentation":"Raised by Outcomes::CsvImporter#validate_headers when the header row contains fields that are neither in REQUIRED_FIELDS nor OPTIONAL_FIELDS. The importer whitelists headers; any unrecognized column name before 'ratings' triggers this ParseError listing the invalid fields. This prevents silently ignoring typo'd or unsupported columns.","triggerScenarios":"Header containing a typo such as 'vendor_Guid' or 'titel'; an extra column like 'display_name' that is not in the whitelist; copy-pasting headers from a different import format with extra columns.","commonSituations":"Migrating CSVs from another LMS with different column names; manual edits introducing typos; older/newer template versions whose headers no longer match this importer's whitelist.","solutions":["Remove or rename the offending columns listed in the error to match the allowed field names exactly.","Compare your headers against the template's valid fields (REQUIRED_FIELDS + OPTIONAL_FIELDS) and fix typos.","Split data that does not belong in this import into a separate process instead of adding extra columns."],"exampleFix":"// before\nvendor_guid,title,display_name,ratings\n// after\nvendor_guid,title,ratings","handlingStrategy":"validation","validationCode":"ALLOWED = REQUIRED_FIELDS + OPTIONAL_FIELDS\nheaders = CSV.open(path, &:first).map(&:to_sym)\ninvalid = headers - ALLOWED\nraise \"unknown columns: #{invalid.inspect}\" unless invalid.empty?","typeGuard":null,"tryCatchPattern":"begin\n  importer.parse_file\nrescue Outcomes::CsvImporter::ParseError => e\n  log_and_report(e.message) # list invalid fields to the uploader\nend","preventionTips":["Keep extra data out of the import CSV — only whitelisted columns","Spell-check header names against the template","Re-derive headers from the template after any manual edit"],"tags":["csv","headers","validation","import"],"backgroundTag":"schema-validation-failed","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"}