{"record":{"id":"5ed58181f4e3d5a2","repo":"instructure/canvas-lms","slug":"you-do-not-have-permission-to-view-this-course-files","errorCode":null,"errorMessage":"You do not have permission to view this course.","messagePattern":"You do not have permission to view this course\\.","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/interfaces/files_connection_interface.rb","lineNumber":42,"sourceCode":"    argument :user_id, ID, <<~MD, required: false\n      only return files for the given user. Defaults to\n      the current user.\n    MD\n    argument :search_term, String, <<~MD, required: false\n      only return files whose name matches this search term\n    MD\n  end\n\n  def files_scope(course, user_id = nil, search_term = nil)\n    scoped_user = user_id.nil? ? current_user : User.find_by(id: user_id)\n\n    # If user_id was provided but user not found, return no files\n    return Attachment.none if user_id.present? && scoped_user.nil?\n\n    # Check if current user has permission to view files as the scoped user\n    unless current_user.can_current_user_view_as_user(course, scoped_user)\n      # Current user lacks permissions to view as the scoped user\n      raise GraphQL::ExecutionError, \"You do not have permission to view this course.\"\n    end\n\n    files = course.attachments.not_deleted\n\n    # Apply search term filter if provided\n    if search_term.present?\n      files = files.where(Attachment.wildcard(:display_name, search_term))\n    end\n\n    # Only return files the user has permission to view, ensure we return a scope\n    if scoped_user && course.grants_right?(scoped_user, :read_as_admin)\n      files\n    else\n      visible_files = files.where(\n        \"attachments.context_id = ? AND attachments.context_type = ?\",\n        course.id,\n        course.class.to_s\n      )","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/interfaces/files_connection_interface.rb#L24-L60","documentation":"files_scope in files_connection_interface.rb raises this GraphQL::ExecutionError when the current user cannot view course files on behalf of the requested scoped user, via current_user.can_current_user_view_as_user(course, scoped_user). Like the discussions variant, it guards the user_id masquerade path only; if the scoped user doesn't exist, Attachment.none is returned instead of raising.","triggerScenarios":"Querying course.filesConnection (files_connection) with a user_id argument for another user — a student targeting a peer's id, or a caller without admin 'view as' permission.","commonSituations":"Scripts iterating student file listings with the wrong token; post-enrollment-change permissions (observer/teacher roles revoked) invalidating previously working user_id queries.","solutions":["Drop the user_id argument or set it to the current user's id.","Request an admin token with 'View as' permission for the course.","Log in as the target user and query without masquerading.","Verify the viewer's course role actually grants can_current_user_view_as_user before calling.","If the target user was recently removed from the course, confirm scoped_user is resolvable in that course context."],"exampleFix":"// before\nconst vars = { courseId: \"1\", userId: \"42\" }\n// after\nconst vars = { courseId: \"1\", userId: currentUser.id } // or omit userId entirely","handlingStrategy":"validation","validationCode":"function canQueryFilesAs(targetUserId) {\n  if (targetUserId == null || String(targetUserId) === String(currentUser.id)) return true\n  return currentUser.permissions.includes(\"view_as\") // admin-level check\n}\nif (!canQueryFilesAs(variables.userId)) throw new Error(\"not permitted to view files as that user\")","typeGuard":"const targetsSelf = (v) => v?.userId == null || String(v.userId) === String(currentUser.id)","tryCatchPattern":null,"preventionTips":["Default to omitting user_id unless per-user scoping is required","Keep 'View as' admin permissions in mind when designing integrations","Log the effective (viewer, scoped_user) pair in test tooling","Re-test integrations after role changes (e.g. teacher->observer)"],"tags":["graphql","authorization","masquerade","permissions"],"backgroundTag":"permission-denied","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"}