{"record":{"id":"7c91f396a596edeb","repo":"instructure/canvas-lms","slug":"couldn-t-find-valid-settings-for-this-link","errorCode":null,"errorMessage":"Couldn't find valid settings for this link","messagePattern":"Couldn't find valid settings for this link","errorType":"exception","errorClass":"InvalidSettingsError","httpStatus":null,"severity":"error","filePath":"app/controllers/external_tools_controller.rb","lineNumber":787,"sourceCode":"      # If the resource_link doesn't have a url, then use the provided url to look up the tool\n      tool = Lti::ToolFinder.from_url(provided_url, context, preferred_client_id: client_id, prefer_1_1:)\n      unless tool\n        invalid_settings_error\n      end\n      [tool, provided_url]\n    elsif resource_link.url\n      tool = resource_link.current_external_tool context\n      unless tool\n        invalid_settings_error\n      end\n      [tool, resource_link.url]\n    else\n      invalid_settings_error\n    end\n  end\n\n  def invalid_settings_error\n    raise InvalidSettingsError, t(\"#application.errors.invalid_external_tool\", \"Couldn't find valid settings for this link\")\n  end\n\n  # @API Get a sessionless launch url for an external tool.\n  # Returns a sessionless launch url for an external tool.\n  # Prefers the resource_link_lookup_uuid, but defaults to the other passed\n  #   parameters id, url, and launch_type\n  #\n  # NOTE: Either the resource_link_lookup_uuid, id, or url must be provided unless launch_type is assessment or module_item.\n  #\n  # @argument id [String]\n  #   The external id of the tool to launch.\n  #\n  # @argument url [String]\n  #   The LTI launch url for the external tool.\n  #\n  # @argument assignment_id [String]\n  #   The assignment id for an assignment launch. Required if launch_type is set to \"assessment\".\n  #","sourceCodeStart":769,"sourceCodeEnd":805,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/controllers/external_tools_controller.rb#L769-L805","documentation":"ExternalToolsController raises InvalidSettingsError 'Couldn't find valid settings for this link' when the launch request cannot resolve valid LTI settings for the requested tool/link. invalid_settings_error is the central helper used whenever tool settings resolution fails.","triggerScenarios":"LTI launch (basic_lti_launch_request or related actions) where the tool has no matching settings for the given id/url/resource link — e.g. wrong tool id, launch URL not configured in the tool, or launch_type not matching configured settings.","commonSituations":"Tool configured at wrong account level; URL-based launch where the tool has no url property; copied course with tool re-installed under a new id; LTI 1.1/1.3 configuration mismatch.","solutions":["Verify the external tool (id/url) is installed on the context account or course","Check the tool's LTI settings include the requested URL / launch type","Re-install or re-configure the tool with correct settings","Confirm you're launching in the same context the tool was added to"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const tool = await getExternalTool(contextId, toolId); if (!tool || !tool.url && launchType === 'url') throw new Error('tool lacks configured launch settings');","typeGuard":"const isLaunchable = (t) => Boolean(t && (t.url || t.domain || t.lti_version));","tryCatchPattern":"try { await launch(toolId) } catch (e) { if (/Couldn't find valid settings/.test(e.message)) showToolConfigError(); else throw e; }","preventionTips":["Verify tool installation on the exact context before launching","Keep tool LTI settings (url/domain/launch type) in sync with client launch calls","Re-check configuration after course copies or tool reinstalls"],"tags":["canvas","lti","external-tools","launch"],"backgroundTag":"invalid-config-value","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"}