instructure/canvas-lms · error · SubmissionError
Invalid file type
Error message
Invalid file type
What it means
CreateSubmissionDraft#verify_allowed_extensions! enforces the assignment's allowed_extensions list for online_upload submissions. If the assignment restricts extensions and any attachment's extension is not in the list (case-insensitive), it raises SubmissionError "Invalid file type".
Solutions
- Convert/rename the file so its extension matches one in the assignment's allowed_extensions.
- Check the assignment's allowedExtensions via GraphQL and validate client-side before upload.
- Ask the instructor to update allowed_extensions if the file type should be permitted.
- Ensure the uploaded Attachment actually retains its extension (after_extension not empty).
Example fix
// before
fileIds: [idOf("report.exe")]
// after
fileIds: [idOf("report.pdf")] // extension now in allowedExtensions: ["pdf"] Defensive patterns
Strategy: validation
Validate before calling
const allowed = (assignment.allowedExtensions || []).map(e => e.toLowerCase())
const bad = files.filter(f => !allowed.includes(f.name.split('.').pop().toLowerCase()))
if (assignment.allowedExtensions?.length && bad.length) throw new SkipError('invalid file type: ' + bad.map(f => f.name)) Type guard
function hasAllowedExtension(file, allowed) { return !allowed?.length || allowed.includes((file.name.split('.').pop() || '').toLowerCase()); } Try / catch
try {
await createSubmissionDraft({ fileIds })
} catch (e) {
if (e.message === 'Invalid file type') {
alertUserToConvertFile(assignment.allowedExtensions)
} else throw e;
} Prevention
- Read allowedExtensions from the assignment and filter in the file picker (accept attribute).
- Convert files to a permitted format before upload rather than renaming.
- Watch for files with no extension when restrictions exist.
When it happens
Trigger: Drafting a file upload submission where assignment.allowed_extensions is non-blank and an attachment's after_extension (downcased) is not included, e.g. uploading .exe when only .pdf,.docx allowed; attachment with no extension while restrictions exist.
Common situations: Instructor tightened allowed extensions after students already uploaded files; file renamed without actually converting format; macOS hidden extension issues; uploading files with uppercase extensions is fine but files with none are rejected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
- All ConversationMessages must exist within the same…
- Anonymous assignments must be manually posted
- Assignment overrides are not allowed in the parent…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/26e0abdd2022da51.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/create_submission_draft.rb:162
end
def validate_file_ids!(file_id_attachments, valid_attachment_ids)
file_ids = file_id_attachments.pluck(:id).map(&:to_s)
file_ids.each do |file_id|
next if valid_attachment_ids.include?(file_id)
raise SubmissionError, I18n.t(
"No attachments found for the following ids: %{ids}",
{ ids: file_ids - valid_attachment_ids }
)
end
end
# TODO: move this into the model
def verify_allowed_extensions!(assignment, attachments)
return if assignment.allowed_extensions.blank?
raise SubmissionError, I18n.t("Invalid file type") unless attachments.all? do |attachment|
attachment_extension = attachment.after_extension || ""
assignment.allowed_extensions.include?(attachment_extension.downcase)
end
end
def get_attachment_ids(file_ids)
return [] if file_ids.empty?
joined_file_ids = file_ids.to_a.join(",")
sql = <<~SQL.squish
SELECT
p.a_id,
p.ra_id
FROM
(
(
SELECT
a.id as a_id,View on GitHub (pinned to 1c9f0bb801)