we-promise/sure · error · Provider::Sophtron::Error

not_found

not_found

Error message

Sophtron resource not found

What it means

Provider::Sophtron raises this Error with error_type=:not_found when Sophtron responds HTTP 404. It signals that the resource referenced by the request path (job ID, institution ID, customer ID, account ID) does not exist under the authenticated API user.

Source

Thrown at app/models/provider/sophtron.rb:363

      }
    end

    def handle_response(response, parse_json: true)
      body = response.body.to_s

      case response.code.to_i
      when 200, 201, 204
        return {} if body.strip.blank?

        parse_json ? JSON.parse(body, symbolize_names: true) : parse_optional_json(body)
      when 400
        raise Error.new("Bad request to Sophtron API: #{body}", :bad_request, details: body)
      when 401
        raise Error.new("Invalid Sophtron User ID or Access Key", :unauthorized, details: body)
      when 403
        raise Error.new("Access forbidden by Sophtron", :access_forbidden, details: body)
      when 404
        raise Error.new("Sophtron resource not found", :not_found, details: body)
      when 429
        raise Error.new("Sophtron rate limit exceeded. Please try again later.", :rate_limited, details: body)
      else
        raise Error.new(
          "Sophtron API request failed: #{response.code} #{response.message} - #{body}",
          :fetch_failed,
          details: body
        )
      end
    rescue JSON::ParserError => e
      raise Error.new("Invalid JSON response from Sophtron API: #{e.message}", :invalid_response, details: body)
    end

    def parse_optional_json(body)
      JSON.parse(body, symbolize_names: true)
    rescue JSON::ParserError
      body
    end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Re-enumerate from a parent resource (list customers/accounts) instead of reusing a persisted ID
  2. If the ID came from a stored SophtronAccount, mark that account for re-linking or deletion and start a new add-institution job
  3. Verify the ID was obtained from the same Sophtron environment/base_url the client is configured with
  4. Check e.details body - Sophtron usually echoes which resource was missing

Example fix

# before
job = provider.get_job(stale_job_id)

# after - tolerate vanished jobs
begin
  job = provider.get_job(stale_job_id)
rescue Provider::Sophtron::Error => e
  raise if e.error_type != :not_found
  job = provider.start_add_institution_job(institution_id) # fresh job
end
Defensive patterns

Strategy: try-catch

Validate before calling

# Confirm the referenced job/account id came from a live listing
ids = provider.get_accounts(customer_id).map { |a| a[:id] }
raise ArgumentError, "unknown account" unless ids.include?(target_id)

Type guard

def sophtron_not_found?(err)
  err.is_a?(Provider::Sophtron::Error) && err.error_type == :not_found
end

Try / catch

begin
  provider.get_job(job_id)
rescue Provider::Sophtron::Error => e
  raise unless e.error_type == :not_found
  job_id = provider.start_add_institution_job(institution_id).fetch(:id) # re-bootstrap
end

Prevention

When it happens

Trigger: Polling a Sophtron job ID that already expired or belongs to another customer; GET accounts/transactions for a deleted SophtronAccount; referencing an institution_id typo'd or removed from Sophtron's catalog; V2 customer endpoints after the customer record was deleted server-side.

Common situations: Resuming an old sync from a stale job ID persisted on SophtronAccount.current_job; a bank connection deleted from the Sophtron side while the local SophtronAccount still links to it; environment mismatch where IDs created in sandbox are requested from production.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/34cc887596fa06c3. Report an issue: GitHub.