instructure/canvas-lms · error · ContentUnavailable
No pageID or fileID provided
Error message
No pageID or fileID provided
What it means
StudyAssist::ContentUnavailable with message 'No pageID or fileID provided' is raised by resolve_content when neither page_id nor file_id was supplied, so there is no source content to extract text from for the LLM call. It is the terminal else branch of the page/file resolution if/elsif chain.
Solutions
- Pass page_id: or file_id: when constructing StudyAssist for content-backed tools
- Verify the controller/GraphQL layer maps the incoming content identifier params correctly
- Guard the caller: only invoke StudyAssist with a content context present
- Check params[:page_id].present? / params[:file_id].present? client-side before submitting
Example fix
// before StudyAssist.new(course: @course, user: @user, prompt: prompt).call // after StudyAssist.new(course: @course, user: @user, prompt: prompt, page_id: params[:page_id], file_id: params[:file_id]).call
Defensive patterns
Strategy: validation
Validate before calling
raise ActionController::BadRequest if params[:page_id].blank? && params[:file_id].blank?
Type guard
null
Try / catch
begin
StudyAssist.new(course:, user:, prompt:, page_id:, file_id:).call
rescue StudyAssist::ContentUnavailable => e
render json: { error: e.message }, status: :bad_request
end Prevention
- Always pass a content identifier for content-backed tools
- Validate params presence in controller before service call
- Keep frontend param names aligned (page_id vs pageId)
When it happens
Trigger: Calling StudyAssist.new(course:, user:, prompt:) without page_id: and without file_id: (both nil/blank) on a tool whose prompt matched and requires source content, then invoking #call.
Common situations: Frontend omits the content identifier when the user didn't open a page/file context; API params named differently (e.g. page_url vs page_id) so page_id arrives blank; callers testing chip-only tools but hitting a content-requiring tool.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- tool_key
- An institutional tag category did not pass validation
- app '# ' must be one of: #
- Artifact required for assessing
- Assessment type required for assessing
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/b673575f6844f889.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/study_assist.rb:146
chips = TOOLS.each_with_object([]) do |(_, cfg), memo|
memo << { chip: cfg[:chip_label], prompt: cfg[:chip_label] } if @course.feature_enabled?(cfg[:feature_flag])
end
{ chips: }
end
# --- Content resolution ---
def resolve_content
page_id = @state["pageID"] || @state[:pageID]
file_id = @state["fileID"] || @state[:fileID]
content =
if page_id.present?
resolve_page(page_id)
elsif file_id.present?
resolve_file(file_id)
else
raise ContentUnavailable, "No pageID or fileID provided"
end
if content.text.length > MAX_CONTENT_CHARS
raise ContentTooLarge, "Content exceeds #{MAX_CONTENT_CHARS} character limit"
end
content
end
def resolve_page(page_id)
page = @course.wiki_pages.not_deleted.find_by(url: page_id)
raise ContentUnavailable, "Page not found" if page.nil?
raise ContentUnavailable, "Page access denied" unless page.grants_right?(@user, :read)
shard_safe_key = shard_safe_cache_key_for(page)
text = Rails.cache.fetch(text_cache_key_for(:page, shard_safe_key), expires_in: TEXT_CACHE_TTL) do
html_to_text(page.body.to_s)
endView on GitHub (pinned to 1c9f0bb801)