{"record":{"id":"8b390f3a94f122eb","repo":"we-promise/sure","slug":"sophtron-provider-is-not-configured","errorCode":null,"errorMessage":"Sophtron provider is not configured","messagePattern":"Sophtron provider is not configured","errorType":"exception","errorClass":"StandardError","httpStatus":null,"severity":"error","filePath":"app/models/sophtron_item.rb","lineNumber":78,"sourceCode":"  end\n\n  # Imports the latest account and transaction data from Sophtron.\n  #\n  # This method fetches all accounts and transactions from the Sophtron API\n  # and updates the local database accordingly. It will:\n  # - Fetch all accounts associated with the Sophtron connection\n  # - Create new SophtronAccount records for newly discovered accounts\n  # - Update existing linked accounts with latest data\n  # - Fetch and store transactions for all linked accounts\n  #\n  # @return [Hash] Import results with counts of accounts and transactions imported\n  # @raise [StandardError] if the Sophtron provider is not configured\n  # @raise [Provider::Sophtron::Error] if the Sophtron API returns an error\n  def import_latest_sophtron_data(sync: nil)\n    provider = sophtron_provider\n    unless provider\n      Rails.logger.error \"SophtronItem #{id} - Cannot import: Sophtron provider is not configured (missing API key)\"\n      raise StandardError.new(\"Sophtron provider is not configured\")\n    end\n\n    SophtronItem::Importer.new(self, sophtron_provider: provider, sync: sync).import\n  rescue => e\n    Rails.logger.error \"SophtronItem #{id} - Failed to import data: #{e.message}\"\n    raise\n  end\n\n  def linked_visible_sophtron_accounts\n    sophtron_accounts.joins(:account).merge(Account.visible)\n  end\n\n  def automatic_sync_sophtron_accounts\n    return linked_visible_sophtron_accounts.none if manual_sync?\n\n    linked_visible_sophtron_accounts.automatic_sync\n  end\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/sophtron_item.rb#L60-L96","documentation":"SophtronItem#import_latest_sophtron_data first builds a provider via sophtron_provider; when that returns nil (user_id or access_key missing on the record) it raises a plain StandardError before any API call, after logging that the Sophtron provider is not configured. The rescue block re-logs and re-raises, so sync jobs see the original error.","triggerScenarios":"Enqueueing an import/sync for a SophtronItem whose user_id or access_key attribute is blank; records created before credentials were saved; encrypted attributes reading as nil because ACTIVE_RECORD_ENCRYPTION_* keys are missing or rotated since the values were written (encryption_ready? was false at write, true at read, or key mismatch).","commonSituations":"Deployments where ActiveRecord Encryption env vars were added or changed after SophtronItems already existed; sync scheduler picking up half-onboarded items; staging copies of production data where the deterministic key differs, so ciphertexts fail to decrypt to nil.","solutions":["Ensure the SophtronItem has both user_id and access_key set before scheduling syncs (validate presence beyond just on: :create)","Verify ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY/DETERIVATION_SALT/DETERMINISTIC_KEY match the values used when the credentials were stored","Re-enter the credentials through the settings UI (which re-encrypts with current keys)","Guard the scheduler: skip SophtronItems where sophtron_provider is nil and surface them in an 'needs setup' list instead of raising"],"exampleFix":"# before\nSophtronItem.syncable.find_each(&:import_latest_sophtron_data)\n\n# after\nSophtronItem.syncable.find_each do |item|\n  unless item.sophtron_provider\n    item.update!(status: :requires_update)\n    next\n  end\n  item.import_latest_sophtron_data\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, \"SophtronItem #{item.id} lacks credentials\" if item.user_id.blank? || item.access_key.blank?\nitem.import_latest_sophtron_data(sync: sync)","typeGuard":"def sophtron_item_configured?(item)\n  item.user_id.present? && item.access_key.present? && item.sophtron_provider.present?\nend","tryCatchPattern":"begin\n  item.import_latest_sophtron_data\nrescue StandardError => e\n  raise unless e.message == \"Sophtron provider is not configured\"\n  item.update!(status: :requires_update)\n  NotifyUserCredentialsMissingJob.perform_later(item)\nend","preventionTips":["Validate user_id/access_key presence on every save, not only on: :create","Keep ACTIVE_RECORD_ENCRYPTION_* values identical across all servers that read these columns","Smoke-test one import immediately after credential entry so misconfig surfaces at setup time","Exclude unconfigured items from the sync scheduler's query"],"tags":["sophtron","configuration","missing-credentials","encryption","sync-job"],"backgroundTag":"missing-api-key","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}