{"record":{"id":"286622e60c88dcda","repo":"we-promise/sure","slug":"trading-212-provider-is-not-configured","errorCode":null,"errorMessage":"Trading 212 provider is not configured","messagePattern":"Trading 212 provider is not configured","errorType":"exception","errorClass":"StandardError","httpStatus":null,"severity":"error","filePath":"app/models/trading212_item.rb","lineNumber":35,"sourceCode":"  validates :api_secret, presence: true, on: :create\n\n  scope :active, -> { where(scheduled_for_deletion: false) }\n  scope :syncable, -> { active.where.not(api_key: [ nil, \"\" ]) }\n  scope :ordered, -> { order(created_at: :desc) }\n  scope :needs_update, -> { where(status: :requires_update) }\n\n  def destroy_later\n    update!(scheduled_for_deletion: true)\n    DestroyJob.perform_later(self)\n  end\n\n  def credentials_configured?\n    api_key.present? && api_secret.present?\n  end\n\n  def import_latest_data\n    provider = trading212_provider\n    raise StandardError, \"Trading 212 provider is not configured\" unless provider\n\n    Trading212Item::Importer.new(self, provider: provider).import\n  rescue => e\n    DebugLogEntry.capture(\n      category: \"sync\",\n      level: \"error\",\n      message: \"Trading212Item #{id} - Failed to import data: #{e.message}\",\n      source: \"trading212\",\n      family: family,\n      provider_key: \"trading212\"\n    )\n    raise\n  end\n\n  def process_accounts\n    return [] if trading212_accounts.empty?\n\n    linked_trading212_accounts.includes(account_provider: :account).each_with_object([]) do |t212_account, results|","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/trading212_item.rb#L17-L53","documentation":"Raised as a plain StandardError by Trading212Item#import_latest_data (app/models/trading212_item.rb:35) when trading212_provider returns nil. The provider factory (Trading212Item::Provided#trading212_provider, app/models/trading212_item/provided.rb:4) returns nil unless credentials_configured? is true, i.e. both api_key and api_secret are present. So the 'provider is not configured' text really means 'this item is missing one or both stored credentials'. The rescue also writes a DebugLogEntry (category sync, provider_key trading212) before re-raising.","triggerScenarios":"Calling item.import_latest_data on a Trading212Item whose api_key or api_secret is blank: items created before credentials were added, secrets wiped by an encryption-key rotation or a failed deterministic decrypt, or records loaded after api_key was cleared. Any sync job (Syncable) that drives perform_sync -> import_latest_data without first checking credentials_configured?.","commonSituations":"Re-encrypting/migrating the database without ACTIVE_RECORD_ENCRYPTION keys leaving credential columns unreadable; manually nulling credentials in a console; racing a destroy_later (scheduled_for_deletion) item that still gets enqueued for one last sync.","solutions":["Re-enter the Trading 212 API key and secret on the item (settings UI or item.update!(api_key: ..., api_secret: ...)) so credentials_configured? returns true.","Guard the call site: skip or mark requires_update when item.credentials_configured? is false instead of letting StandardError surface.","If it fires right after an encryption-key change, verify ACTIVE_RECORD_ENCRYPTION_* env vars match the ones used when the secrets were stored.","Check /settings/debug (DebugLogEntry, source trading212) for the captured entry to confirm which item and family are affected."],"exampleFix":"// before\nitem.import_latest_data # raises when api_key/api_secret blank\n\n// after\nif item.credentials_configured?\n  item.import_latest_data\nelse\n  item.update!(status: :requires_update)\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'configure credentials first' unless item.credentials_configured?\nitem.import_latest_data","typeGuard":"item.credentials_configured? # -> api_key.present? && api_secret.present?","tryCatchPattern":"begin\n  item.import_latest_data\nrescue StandardError => e\n  # message is already captured to DebugLogEntry (source: trading212)\n  Rails.logger.warn(\"trading212 import failed: #{e.message}\")\n  item.update!(status: :requires_update)\nend","preventionTips":["Gate sync scheduling on the syncable scope so credential-less items are never synced.","After any encryption-key change, smoke-test one provider import before bulk syncing.","Surf the item's requires_update status in the UI so users re-enter credentials proactively."],"tags":["rails","trading212","provider-sync","missing-credentials","secrets"],"backgroundTag":"provider-not-configured","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}