{"record":{"id":"e04b53f03e46b1ec","repo":"instructure/canvas-lms","slug":"you-do-not-have-permission-to-view-this-course-pages","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/pages_connection_interface.rb","lineNumber":42,"sourceCode":"    argument :user_id, ID, <<~MD, required: false\n      only return pages for the given user. Defaults to\n      the current user.\n    MD\n    argument :search_term, String, <<~MD, required: false\n      only return pages whose title matches this search term\n    MD\n  end\n\n  def pages_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 pages\n    return WikiPage.none if user_id.present? && scoped_user.nil?\n\n    # Check if current user has permission to view pages 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    pages = course.wiki.wiki_pages.not_deleted\n\n    # Apply search term filter if provided\n    if search_term.present?\n      pages = pages.where(WikiPage.wildcard(:title, search_term))\n    end\n\n    # Only return pages the user has permission to view\n    WikiPages::ScopedToUser.new(course, scoped_user, pages).scope\n  end\n\n  field :pages_connection,\n        ::Types::PageType.connection_type,\n        <<~MD,\n          returns a list of wiki pages.\n        MD","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/interfaces/pages_connection_interface.rb#L24-L60","documentation":"pages_scope in pages_connection_interface.rb raises this GraphQL::ExecutionError when current_user cannot view course wiki pages as the requested scoped user (can_current_user_view_as_user fails). The masquerade guard is identical to the discussions/files interfaces; nonexistent scoped_user returns WikiPage.none instead of raising.","triggerScenarios":"Querying course.pagesConnection (pages_connection) with a user_id argument identifying another user the caller may not view as, e.g. student A enumerating student B's page activity.","commonSituations":"Automated reports passing a fixed user_id while auth tokens rotate; custom tools built before the scoped_user permission guard was added now failing on upgrade.","solutions":["Remove the user_id argument or pass the caller's own id.","Use an admin token permitted to view as the target user.","Log in as the target user.","Pre-check can_current_user_view_as_user (or replicate its role rules) before issuing the query.","Confirm the scoped user still exists and is enrolled in the course."],"exampleFix":"// before\npagesConnection(userId: $otherUserId) { nodes { title } }\n// after\npagesConnection { nodes { title } } // caller-scoped, no masquerade","handlingStrategy":"validation","validationCode":"const assertCanViewPagesAs = (vars) => {\n  if (vars.userId && vars.userId !== currentUser.id && !currentUser.isCourseAdmin)\n    throw new Error(\"pagesConnection userId requires view-as permission\")\n}\nassertCanViewPagesAs(variables)","typeGuard":"const selfOrUndefined = (userId) => userId === undefined || userId === currentUser.id","tryCatchPattern":null,"preventionTips":["Treat user_id arguments on course content connections as privileged","Use admin tokens only in controlled server-side jobs","Validate scoped user exists in the course before querying","Avoid copying user_id params between different users' sessions"],"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"}