{"record":{"id":"d99606061fccb46e","repo":"we-promise/sure","slug":"either-api-token-or-all-three-username-document-pa","errorCode":null,"errorMessage":"Either API token or all three username/document/password credentials are required","messagePattern":"Either API token or all three username/document/password credentials are required","errorType":"exception","errorClass":"Provider::IndexaCapital::ConfigurationError","httpStatus":null,"severity":"error","filePath":"app/models/provider/indexa_capital.rb","lineNumber":116,"sourceCode":"    ].freeze\n\n    MAX_RETRIES = 3\n    INITIAL_RETRY_DELAY = 2 # seconds\n\n    # Indexa Capital account numbers are 8-char alphanumeric (e.g., \"LPYH3MCQ\")\n    def sanitize_account_number!(account_number)\n      unless account_number.present? && account_number.match?(/\\A[A-Za-z0-9]+\\z/)\n        raise Error.new(\"Invalid account number format: #{account_number}\", :bad_request)\n      end\n    end\n\n    attr_reader :username, :document, :password, :api_token\n\n    def validate_configuration!\n      return if @api_token.present?\n\n      if @username.blank? || @document.blank? || @password.blank?\n        raise ConfigurationError, \"Either API token or all three username/document/password credentials are required\"\n      end\n    end\n\n    def token_auth?\n      @api_token.present?\n    end\n\n    def with_retries(operation_name, max_retries: MAX_RETRIES)\n      retries = 0\n\n      begin\n        yield\n      rescue *RETRYABLE_ERRORS => e\n        retries += 1\n\n        if retries <= max_retries\n          delay = calculate_retry_delay(retries)\n          Rails.logger.warn(","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/indexa_capital.rb#L98-L134","documentation":"Raised as Provider::IndexaCapital::ConfigurationError when the Indexa Capital provider is configured with neither an API token nor the complete legacy triple (username, document, password). Indexa supports two auth modes: token auth (api_token alone) and credential auth (all three of username/document/password required together). validate_configuration! enforces at least one complete mode and fails fast when credentials are half-entered.","triggerScenarios":"Constructing the Indexa provider with only some legacy credentials (e.g. username + password but no document), only a document, or entirely blank credentials and no token. Raises during initialization/first use, before any HTTP request to the Indexa API.","commonSituations":"Users migrating from the legacy email/password login who leave out the document (NIF/ID) field, settings forms that save partially-filled credentials, importers that map only some fields, and new setups where the user skipped generating an API token in the Indexa dashboard.","solutions":["Preferred: create an API token in the Indexa Capital dashboard and configure only that — it replaces all three legacy fields","Otherwise provide ALL three legacy fields: username (email), document (ID/NIF), and password","Audit the stored Indexa credentials for the account and fill in whichever mode you choose completely","Add paired validation in the settings UI (token XOR all-three) so partial saves are blocked with a clear message","After fixing, test the connection with the provider's health/usage call before scheduling syncs"],"exampleFix":"# before: partial legacy credentials saved silently, provider blows up later\nProvider::IndexaCapital.new(username: u, password: p)\n\n# after: enforce a complete auth mode at the boundary\nif api_token.blank? && [username, document, password].any?(&:blank?)\n  raise ConfigurationError, \"Provide either an API token, or username + document + password\"\nend\nProvider::IndexaCapital.new(api_token:, username:, document:, password:)","handlingStrategy":"validation","validationCode":"# Enforce a complete auth mode before building the provider\ncomplete_token_mode  = api_token.present?\ncomplete_legacy_mode = username.present? && document.present? && password.present?\nunless complete_token_mode || complete_legacy_mode\n  raise ArgumentError, \"Indexa requires an API token, or username + document + password\"\nend","typeGuard":"def valid_indexa_auth?(api_token:, username:, document:, password:)\n  api_token.present? || [username, document, password].all? { |c| c.present? }\nend","tryCatchPattern":"begin\n  provider = Provider::IndexaCapital.new(api_token:, username:, document:, password:)\n  provider.validate_connection!\nrescue Provider::IndexaCapital::ConfigurationError => e\n  render_settings_error(message: e.message) # point user to token OR all-three fields\nend","preventionTips":["In the settings UI, make the API token the primary path and mark username/document/password as a grouped legacy set","Disable save until one complete auth mode is filled (paired validation)","Prefer token auth in new setups — fewer fields, fewer failure modes","Re-validate credentials after any provider settings migration"],"tags":["indexa-capital","configuration","authentication","missing-credential","validation"],"backgroundTag":"missing-configuration","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}