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
endView on GitHub (pinned to e69894adb9)
Solutions
- Re-enumerate from a parent resource (list customers/accounts) instead of reusing a persisted ID
- If the ID came from a stored SophtronAccount, mark that account for re-linking or deletion and start a new add-institution job
- Verify the ID was obtained from the same Sophtron environment/base_url the client is configured with
- 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
- Treat persisted Sophtron job/account IDs as cacheable but expirable - re-enumerate on 404
- Never reuse IDs across Sophtron environments
- Expire stored job IDs after a TTL so stale polling cannot continue for days
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.