{"record":{"id":"5eadfbbd5ea366fd","repo":"instructure/canvas-lms","slug":"csp-not-explicitly-set","errorCode":null,"errorMessage":"csp not explicitly set","messagePattern":"csp not explicitly set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/models/csp/account_helper.rb","lineNumber":85,"sourceCode":"  def enable_csp!\n    set_csp_setting!([true, global_id])\n  end\n\n  def disable_csp!\n    set_csp_setting!([false, global_id])\n  end\n\n  def lock_csp!\n    set_csp_locked!(true)\n  end\n\n  def unlock_csp!\n    set_csp_locked!(false)\n  end\n\n  def set_csp_locked!(value)\n    csp_settings = settings[:csp_inherited_data].dup\n    raise \"csp not explicitly set\" unless csp_settings\n\n    csp_settings[:locked] = !!value\n    settings[:csp_inherited_data] = csp_settings\n    save!\n  end\n\n  def set_csp_setting!(value)\n    csp_settings = settings[:csp_inherited_data].dup || {}\n    csp_settings[:value] = value\n    settings[:csp_inherited_data] = csp_settings\n    save!\n  end\n\n  def inherit_csp!\n    settings.delete(:csp_inherited_data)\n    save!\n  end\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/csp/account_helper.rb#L67-L103","documentation":"CSP account helper guard: set_csp_locked! requires that the account already has :csp_inherited_data in its settings hash. If the CSP settings were never initialized (csp not explicitly set via the CSP API/enable path), calling lock_csp!/unlock_csp! on a duplicated nil settings entry raises.","triggerScenarios":"Calling account.unlock_csp! or account.lock_csp!(true/false) on an Account whose settings[:csp_inherited_data] is nil/absent — i.e. CSP was never explicitly enabled or configured for that account (or an ancestor-inherited value was never materialized).","commonSituations":"Admin scripts or jobs toggling CSP lock on accounts that never went through the CSP enable flow; accounts migrated/copied without settings; calling unlock on a fresh account in a spec or console.","solutions":["Enable/configure CSP for the account first (via CSP API or csp account settings) so settings[:csp_inherited_data] exists","Guard the call: only lock/unlock when account.settings[:csp_inherited_data].present?","Use the account's CSP controller/API endpoints instead of calling the helper directly","Initialize settings[:csp_inherited_data] = {locked: value} explicitly in the script before calling set_csp_locked!"],"exampleFix":"// before\naccount.unlock_csp! # RuntimeError: csp not explicitly set\n// after\nif account.settings[:csp_inherited_data].present?\n  account.unlock_csp!\nelse\n  account.enable_csp! # or set csp settings via API first\nend","handlingStrategy":"validation","validationCode":"raise 'csp not configured' unless account.settings[:csp_inherited_data].present?\naccount.unlock_csp!","typeGuard":null,"tryCatchPattern":"begin\n  account.unlock_csp!\nrescue RuntimeError => e\n  raise unless e.message == 'csp not explicitly set'\n  account.enable_csp! # or initialize csp settings\nend","preventionTips":["Always enable/configure CSP through the API/controller flow before locking or unlocking","Check settings[:csp_inherited_data].present? before toggling","In specs, seed csp settings on accounts under test"],"tags":["ruby","rails","csp","account-settings","state"],"backgroundTag":"missing-config-key","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"}