{"record":{"id":"c3b614706036b59a","repo":"instructure/canvas-lms","slug":"cedar-unavailable","errorCode":null,"errorMessage":"Cedar unavailable","messagePattern":"Cedar unavailable","errorType":"exception","errorClass":"CedarUnavailable","httpStatus":null,"severity":"error","filePath":"app/services/study_assist.rb","lineNumber":254,"sourceCode":"      end\n\n      InstStatsd::Statsd.timing(\n        \"study_assist.cedar_call_duration\",\n        time.real,\n        tags: { tool: tool_key.to_s }\n      )\n\n      response.response\n    rescue InstructureMiscPlugin::Extensions::CedarClient::CedarLimitReachedError => e\n      Rails.logger.warn(\"Cedar rate limit exceeded for #{tool_key}: #{e.message}\")\n      raise RateLimited, e.message\n    rescue InstructureMiscPlugin::Extensions::CedarClient::CedarClientError => e\n      Rails.logger.error(\n        \"Cedar error for study_assist tool=#{tool_key} \" \\\n        \"feature_slug=study-assist-#{tool_key} \" \\\n        \"user_global_id=#{@user.global_id}: #{e.message}\"\n      )\n      raise CedarUnavailable, e.message\n    end\n\n    # --- Per-tool prompt + response ---\n\n    def prompt_for_cedar(tool_key, llm_config, content)\n      substitutions = (tool_key == :summarize) ? { KIND: summarize_kind(content) } : {}\n      prompt, = llm_config.generate_prompt_and_options(substitutions:)\n      prompt\n    end\n\n    def summarize_kind(content)\n      case content.kind\n      when :page then \"page\"\n      when :file then \"file\"\n      else \"material\"\n      end\n    end\n","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/study_assist.rb#L236-L272","documentation":"call_cedar rescues generic CedarClientError and re-raises it as CedarUnavailable. This means the Cedar LLM backend itself failed (transport error, 5xx, client misconfiguration) — the request was made but no usable response came back.","triggerScenarios":"call -> call_cedar when CedarClient raises CedarClientError for any tool_key: network failure to Cedar, Cedar returning an HTTP error, or missing/invalid Cedar configuration for the study-assist feature slug.","commonSituations":"Cedar service outage or partial degradation; environment misconfiguration (wrong Cedar endpoint/credentials); feature slug 'study-assist-<tool>' not provisioned; timeouts under load.","solutions":["Read the logged 'Cedar error for study_assist tool=...' line to get the underlying CedarClientError message.","Retry after a short delay if it was a transient outage; the log line distinguishes transient vs config errors.","Verify Cedar endpoint/credentials configuration for the environment.","Confirm the study-assist feature slugs are provisioned/enabled for the account."],"exampleFix":"// before\n# treating CedarUnavailable like a user-input problem\n\n// after\nbegin\n  result = study_assist.call\nrescue StudyAssist::CedarUnavailable => e\n  Rails.logger.error(\"cedar_down=#{e.message}\")\n  render json: { error: 'Study Assist is temporarily unavailable' }, status: :service_unavailable\nend","handlingStrategy":"try-catch","validationCode":"# health-check Cedar before invoking, if a health endpoint exists\n# cedar_healthy = CedarClient.healthcheck.ok?","typeGuard":null,"tryCatchPattern":"begin\n  result = study_assist.call\nrescue StudyAssist::CedarUnavailable => e\n  Rails.logger.error(\"cedar_unavailable=#{e.message}\")\n  render json: { error: 'study_assist_unavailable' }, status: :service_unavailable\nend","preventionTips":["Verify Cedar endpoint/credentials per environment before deploy","Add a health check / smoke test for Cedar in CI and on-call runbooks","Confirm study-assist feature slugs are provisioned for the account"],"tags":["llm","backend","availability"],"backgroundTag":"upstream-api-error","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"}