Commit graph

585 commits

Author SHA1 Message Date
Yuneng Jiang
94a81f003e
bump: litellm-enterprise 0.1.65 -> 0.1.66 2026-09-08 17:40:34 -07:00
Mateo Wang
5b2b5420af
Merge pull request #39626 from BerriAI/litellm_batch_ui_logs
Some checks failed
Unit Tests / proxy-extras (push) Waiting to run
Unit Tests / proxy-infra (push) Waiting to run
Unit Tests / proxy-server (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests / caching-local (push) Waiting to run
Unit Tests / core-utils (push) Waiting to run
Unit Tests / enterprise-package (push) Waiting to run
Unit Tests / enterprise-routing (push) Waiting to run
Unit Tests / integrations (push) Waiting to run
Unit Tests / All Other Providers (push) Waiting to run
Unit Tests / Vertex AI (push) Waiting to run
Unit Tests / misc (push) Waiting to run
Unit Tests / proxy-auth (push) Waiting to run
Unit Tests / proxy-endpoints (push) Waiting to run
Unit Tests / responses-caching-types (push) Waiting to run
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
feat(ui): batch observability on the logs page
2026-09-08 15:19:25 -07:00
yucheng-berri
a0058ed157
fix(hide-secrets): stop redacting benign identifiers (#39879)
* fix(hide-secrets): stop redacting benign identifiers and make redaction deterministic

The OpenAI key detector matched `sk-` anywhere inside a word, so `<task-notification>`
became `<ta[REDACTED]>`, and the Base64 entropy limit of 3.0 flagged ordinary quoted
identifiers such as `"application/json"` and model ids. Redaction also iterated a
hash-seeded set, so the same request produced different bytes on different workers and
broke prompt caching.

- require a standalone `sk-`/`sk_` token with a digit (still catches sk-proj-/sk-ant-)
- raise Base64HighEntropyString limit from 3.0 to the detect-secrets default 4.5
- redact overlapping matches longest-first in a stable order

Resolves LIT-7049

* fix(hide-secrets): treat separators as key boundaries and defer sk_live_ to the stripe detector

The standalone-token boundary also rejected keys glued to a preceding `_`, `-`
or percent-encoded delimiter (`openai_sk-…`, `key-sk-…`, `Bearer%20sk-…`), which
the old pattern redacted, and `sk_live_…` was counted by both the OpenAI and the
Stripe detector.

* fix(hide-secrets): keep the openai key scan linear on repeated sk separators

The digit requirement was a lookahead, so every `sk` inside a long
`[a-zA-Z0-9_-]` run re-scanned the rest of that run looking for a digit.
100 KB of `-sk-` took over 5s in the worker's event loop and the proxy
closed the connection without a response. The check now runs once per
match in `analyze_string` instead.

* chore(hide-secrets): remove redundant performance test comment

* fix(hide-secrets): consume complete openai key tokens

* chore(hide-secrets): remove redundant fixture comment

* chore(hide-secrets): remove redundant test docstrings

* fix(hide-secrets): redact whole stripe live keys

* style(hide-secrets): wrap secret sorting key
2026-09-05 11:47:36 -07:00
Yuneng Jiang
88985d00e2
bump: litellm-enterprise 0.1.64 -> 0.1.65, litellm-proxy-extras 0.4.93 -> 0.4.94 2026-09-05 09:58:44 -07:00
mateo-berri
95d721ffe6 refactor(batches): drop docstrings restating the org fallbacks 2026-09-05 02:06:40 -07:00
mateo-berri
814c151b02 fix(batches): mask api base credentials on batch cost rows 2026-09-05 01:35:09 -07:00
mateo-berri
ed2408f28a Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_batch_ui_logs 2026-09-05 00:15:42 -07:00
yuneng-jiang
29ac88ebc6
fix(batches): register ownership for every batch create path (#39810)
Some checks failed
Unit Tests / caching-local (push) Waiting to run
Unit Tests / core-utils (push) Waiting to run
Unit Tests / enterprise-package (push) Waiting to run
Unit Tests / proxy-auth (push) Waiting to run
Unit Tests / proxy-endpoints (push) Waiting to run
Unit Tests / proxy-extras (push) Waiting to run
Unit Tests / proxy-infra (push) Waiting to run
Unit Tests / proxy-server (push) Waiting to run
Unit Tests / responses-caching-types (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Waiting to run
Unit Tests: Proxy DB Operations / auth-checks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests / enterprise-routing (push) Waiting to run
Unit Tests / integrations (push) Waiting to run
Unit Tests / All Other Providers (push) Waiting to run
Unit Tests / Vertex AI (push) Waiting to run
Unit Tests / misc (push) Waiting to run
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
* fix(batches): register ownership for every batch create path

Since the team isolation change, the managed files hook decided whether a
response came from a create by looking for the managed input file id on it,
which only the unified input path sets. Batches created from a model-encoded
input file id, a model param, or a raw provider id with ?provider= never got
an ownership row, so they vanished from GET /v1/batches for the key that
created them.

The create endpoint now stamps a create marker on the response before the
hooks run, and the hook keys ownership registration and the batch-created
metric on that marker instead of on the input id format.

* test(batches): assert ownership registration through the managed files hook

The endpoint tests asserted the private create marker, which is wiring, not
behaviour. They now run the create through the real managed files hook and
assert the ownership row is written for the creating key on every create
path, with the unified path driven by a genuine encoded input file id
instead of patched decoders.
2026-09-04 23:59:51 -07:00
mateo-berri
221d08d643 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_batch_ui_logs
# Conflicts:
#	litellm/batches/batch_utils.py
2026-09-04 21:51:52 -07:00
mateo-berri
217cb7da65 fix(managed_files): resolve the creator org through the cached team lookup
Batch creation snapshotted the team's organization with a direct
litellm_teamtable query on every create. Go through get_team_object
instead, which serves the team auth already cached and only falls back
to the database when the team was never cached.
2026-09-04 20:30:33 -07:00
mateo-berri
9c068117e7 chore: merge origin/litellm_internal_staging into litellm_decrease_anys_opus5_r4 2026-09-04 18:59:35 -07:00
mateo-berri
8debf8294c fix(batches): resolve a legacy row's org from the key's organization_id and keep the Batch label on grouped rows 2026-09-04 12:42:39 -07:00
mateo-berri
7e51fbc819 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_batch_ui_logs
# Conflicts:
#	tests/proxy_unit_tests/test_check_batch_cost.py
2026-09-04 12:00:14 -07:00
mubashir1osmani
bb5a960317 Merge remote-tracking branch 'berri/litellm_internal_staging' into litellm_batch_ui_logs 2026-09-03 19:45:38 -04:00
mateo-berri
f1f0294796 Merge branch 'litellm_internal_staging' of https://github.com/BerriAI/litellm into litellm_fix-batch-spend-key-double-hash-bcae 2026-09-03 16:36:12 -07:00
ryan-crabbe-berri
a53c550951
Merge pull request #39661 from BerriAI/litellm_lit_4741_copy_id_search
feat(ui): find rows by a pasted ID on keys, agents, memory, audit, and request logs
2026-09-03 16:17:59 -07:00
mubashir1osmani
35371a34c1 fix(batches): keep team org attribution when the key lookup fails 2026-09-03 19:09:45 -04:00
ryan-crabbe-berri
9baa19c7d1 fix(proxy): stop hashing raw sk- values in list searches
The search= param on /key/list, /audit, and /spend/logs/ui, plus key_hash= on /key/list, now compare the pasted value verbatim. Only a copied key ID (the hash) matches, so a raw virtual key never needs to travel in a GET query string

Claude-Session: https://claude.ai/code/session_01Q5sbiogJzPcCRmYSbaHxZf
2026-09-03 15:54:42 -07:00
mubashir1osmani
0d7976116e fix(batches): resolve team-scoped keys' org at creation for the snapshot 2026-09-03 18:51:56 -04:00
mubashir1osmani
7fb4b427ce feat(batches): snapshot the creating key's org on the managed object row 2026-09-03 18:36:05 -04:00
ryan-crabbe-berri
4811041048 feat(proxy): add a search param to key, memory, audit, and spend log listings
GET /key/list?search= matches the key hash (a raw sk- key is hashed
first) or a case-insensitive alias substring, and key_hash= now hashes a
raw sk- value too. GET /v1/memory?search= matches a key prefix or an
exact memory_id. GET /audit?search= matches id, object_id, changed_by,
or changed_by_api_key. GET /spend/logs/ui?search= matches request_id
across all time and api_key, team_id, user, end_user, session_id, or
model_id inside the date window; session grouping is skipped while a
search is active.

Claude-Session: https://claude.ai/code/session_01Q5sbiogJzPcCRmYSbaHxZf
2026-09-03 15:20:13 -07:00
yuneng-jiang
bed4086619
Merge pull request #33536 from BerriAI/litellm_/rbac-batches-action-items-c00ade
feat(proxy): enforce team isolation for provider-format batch ids and output files
2026-09-03 15:07:59 -07:00
mubashir1osmani
c276813cb4 feat(batches): enrich batch cost rows with breakdown, identity, session, and org spend 2026-09-03 17:23:53 -04:00
Yuneng Jiang
ba9bb75298
bump: litellm-enterprise 0.1.63 -> 0.1.64, litellm-proxy-extras 0.4.92 -> 0.4.93 2026-09-03 10:53:50 -07:00
Cursor Agent
63579f1e35
fix(spend-tracking): keep batch spend keys joinable after v1.99 provenance gate
Batch cost attribution and the legacy queue endpoint already store the
VerificationToken hash in user_api_key, but omitted user_api_key_hash.
Since v1.99 the spend-log writer re-hashes any key without that provenance
flag, so DailyUserSpend.api_key no longer joins VerificationToken and Usage
shows key-hash-... rows with null api_key_alias / user_email.

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>
2026-09-03 14:12:57 +00:00
yucheng-berri
ecabfbd5af
fix(guardrail): hide-secrets playground redaction and guardrail telemetry (#39398)
* Fix hide-secrets guardrail: playground redaction, UI dropdown entry, spend-log telemetry

The hide-secrets guardrail never implemented apply_guardrail, so the UI test
playground echoed secrets verbatim; it was missing from the Add Guardrail
dropdown; and it recorded no guardrail_information, so Spend Logs could not
distinguish a redacted request from a clean one.

- implement apply_guardrail (unified interface) with use_native_lifecycle_hooks
  so proxied traffic stays on async_pre_call_hook (per-key opt-out and
  data["prompt"] handling live only there)
- record standard_logging_guardrail_information (allow/mask + masked_entity_count)
  via _process_response/_process_error; opted-out keys and legacy nameless
  callback instances record nothing
- advertise hide-secrets in /guardrails/ui/add_guardrail_settings (pre_call only)
  and /guardrails/ui/provider_specific_params with a config model

Resolves LIT-3548

* Fix hide-secrets passthrough telemetry and JSON config input

* fix(guardrails): validate hide-secrets object config before submit

- apply_guardrail treats empty-string-only texts as no input, so no
  false allow is recorded
- the UI object field keeps raw text while editing and blocks submission
  until it parses to a JSON object, instead of posting a string to an
  object-only API
- supported_modes_by_provider keeps its dict[str, list[str]] value type

* fix(guardrails): record no hide-secrets telemetry when nothing was inspected

walk_user_text and the prompt redaction now report how many non-empty
strings they visited; when neither inspected anything (image-only
content, empty strings), the run records no guardrail entry instead of
an 'allow' row that counts a check which never saw any text.
2026-09-03 00:01:03 -07:00
mateo-berri
066652c194 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r4
# Conflicts:
#	basedpyright-code-budget.json
#	litellm/a2a_protocol/utils.py
#	litellm/llms/azure_ai/vector_stores/transformation.py
#	litellm/llms/milvus/vector_stores/transformation.py
#	litellm/llms/openai/vector_stores/transformation.py
#	litellm/llms/ragflow/vector_stores/transformation.py
#	litellm/proxy/container_endpoints/endpoints.py
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-09-02 23:32:10 +00:00
mateo-berri
459858829e refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
Yassin Kortam
25991fe78a
feat(auth): enforce configurable password policy and SSO-only login (#39381)
Adds a configurable password-strength policy (default: min 12 chars,
upper/lower/number/special, all individually toggleable, floored at 8
so a misconfigured minimum cannot disable the length check, and
unicode-aware so an accented letter cannot satisfy the special-
character requirement) enforced on every path that sets a local
user's password: /user/update, /user/bulk_update, and the invitation
onboarding claim flow.

Adds general_settings.disable_password_login_when_sso_enabled, which
rejects username/password login on /login, /v2/login and /v3/login
(including the UI_USERNAME/UI_PASSWORD admin fallback) once ANY
configured SSO provider is FULLY ready: every companion secret/
endpoint an OAuth provider needs, checked independently per provider
so a stray leftover client id for an unused provider can't mask a
different, fully configured one; and for SAML, the optional
python3-saml runtime being importable, checked without letting a
fully-missing package's ModuleNotFoundError take down password login
itself. SSO becomes the enforced boundary for interactive UI access
without an incomplete, mixed, or half-installed SSO setup locking
every admin out or breaking login outright. Master-key API access is
untouched, and unsetting the setting plus a restart restores password
login as the documented recovery path.
2026-09-02 14:28:13 -07:00
Yuneng Jiang
19f21d13e5
bump: litellm-enterprise 0.1.62 -> 0.1.63, litellm-proxy-extras 0.4.91 -> 0.4.92, litellm 1.100.0 -> 1.101.0 2026-09-01 10:59:07 -07:00
mateo-berri
c236bcf241 Merge branch 'litellm_internal_staging' into litellm_decrease_anys_opus5_r2 2026-08-30 12:16:13 -07:00
mateo-berri
43c838f4b9 Merge branch 'litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 21:41:04 -07:00
yassin
2f958f2187 fix(managed_files): match provider-format ids against model_object_id and flat_model_file_ids
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-30 00:51:06 +00:00
yassin
0d729da2b9 fix(managed_files): drop stray blank line from merge
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-30 00:18:25 +00:00
yassin
80081107df Merge origin/litellm_internal_staging into litellm_/rbac-batches-action-items-c00ade
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-30 00:14:27 +00:00
mateo-berri
048e82ec65 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r2
# Conflicts:
#	basedpyright-code-budget.json
#	enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-08-29 15:11:45 -07:00
Mateo Wang
20cfccaf5f
Merge pull request #37208 from BerriAI/litellm_managed_batches_observability
fix(batches): aggregate reasoning tokens and per-line pass/fail counts
2026-08-29 14:43:03 -07:00
Mateo Wang
128d7e5278 refactor(batches): make count_error_file_failed_requests public for the poller import 2026-08-29 14:09:18 -07:00
Mateo Wang
4ef012627d fix: count error-file failures in the batch cost poller path 2026-08-29 12:06:42 -07:00
mateo-berri
fb89695cee Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r2
# Conflicts:
#	litellm/litellm_core_utils/prompt_templates/common_utils.py
#	litellm/litellm_core_utils/token_counter.py
#	litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py
#	litellm/llms/gemini/realtime/transformation.py
#	litellm/proxy/guardrails/guardrail_hooks/presidio.py
2026-08-29 19:01:55 +00:00
mateo-berri
14484d67fd refactor(types): replace Any with real types across 54 more backend files
Second pass over the highest-Any-density modules that the first pass left
untouched: guardrail hooks, the gemini and anthropic transformation layers,
the proxy spend-tracking and pass-through endpoints, and the caching clients.

Untyped `response.json()` bodies and `dict[str, Any]` request payloads are
described once at their boundary with a TypedDict or Protocol, so the fields
read downstream resolve to real types instead of Any. No cast, no type: ignore,
no noqa, and no new Any annotations.
2026-08-29 19:00:43 +00:00
Mateo Wang
c24f821652
Merge pull request #34849 from BerriAI/litellm_keyless_key_managed_resource_owner
fix(managed resources): let keys with no user_id or team_id read their own batches and files
2026-08-29 11:50:00 -07:00
Yuneng Jiang
34355778e6
bump: litellm-enterprise 0.1.61 -> 0.1.62, litellm-proxy-extras 0.4.90 -> 0.4.91 2026-08-29 11:33:32 -07:00
mateo-berri
68f891fd2b Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_keyless_key_managed_resource_owner 2026-08-29 11:33:08 -07:00
Mateo Wang
c3edb95e8d Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_managed_batches_observability
# Conflicts:
#	tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py
2026-08-29 10:56:02 -07:00
Mateo Wang
ed2f1836de
Merge pull request #38738 from BerriAI/litellm_fix_batch_list_page_past_unparseable_rows
fix(batches): fill a managed batch page past rows that will not parse
2026-08-29 10:13:29 -07:00
mateo-berri
c37260a2bd Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5
# Conflicts:
#	basedpyright-code-budget.json
#	enterprise/litellm_enterprise/proxy/audit_logging_endpoints.py
#	litellm/_lazy_imports.py
#	litellm/a2a_protocol/litellm_completion_bridge/transformation.py
#	litellm/integrations/bitbucket/bitbucket_client.py
#	litellm/integrations/compression_interception/handler.py
#	litellm/integrations/prometheus_helpers/prometheus_api.py
#	litellm/litellm_core_utils/model_response_utils.py
#	litellm/litellm_core_utils/url_utils.py
#	litellm/llms/anthropic/experimental_pass_through/context_management/dispatcher.py
#	litellm/llms/anthropic/experimental_pass_through/responses_adapters/handler.py
#	litellm/llms/anthropic/skills/transformation.py
#	litellm/llms/azure/files/handler.py
#	litellm/llms/bedrock/realtime/handler.py
#	litellm/llms/chatgpt/chat/streaming_utils.py
#	litellm/llms/compactifai/chat/transformation.py
#	litellm/llms/oci/chat/cohere.py
#	litellm/llms/vertex_ai/vector_stores/rag_api/transformation.py
#	litellm/proxy/agent_endpoints/agent_registry.py
#	litellm/proxy/client/cli/commands/credentials.py
#	litellm/proxy/client/cli/commands/teams.py
#	litellm/proxy/common_utils/get_routes.py
#	litellm/proxy/db/routing_prisma_wrapper.py
#	litellm/proxy/guardrails/guardrail_hooks/custom_code/sandbox.py
#	litellm/proxy/guardrails/guardrail_hooks/hiddenlayer/hiddenlayer.py
#	litellm/proxy/guardrails/guardrail_hooks/llm_as_a_judge/__init__.py
#	litellm/proxy/guardrails/guardrail_hooks/promptguard/promptguard.py
#	litellm/rust_bridge/responses_websocket.py
#	litellm/secret_managers/secret_manager_handler.py
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-08-29 06:37:10 -07:00
mateo-berri
8d4620649f Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5
# Conflicts:
#	basedpyright-code-budget.json
#	litellm/caching/valkey_semantic_cache.py
#	litellm/integrations/compression_interception/handler.py
#	litellm/integrations/custom_logger.py
#	litellm/llms/custom_httpx/container_handler.py
#	litellm/llms/infinity/rerank/transformation.py
#	litellm/proxy/agent_endpoints/agent_registry.py
#	litellm/repositories/base_repository.py
#	litellm/repositories/credentials_repository.py
#	litellm/repositories/team_repository.py
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-08-29 06:03:33 -07:00
mateo-berri
47d8ce6d10 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_0826
# Conflicts:
#	basedpyright-code-budget.json
#	litellm/llms/soniox/common_utils.py
#	ruff-strict-budget.json
#	type-discipline-budget.json
2026-08-29 03:29:39 -07:00
mateo-berri
3bbd2fac33 fix(batches): fill a managed batch page past rows that will not parse
The managed batch listing fetched one page of rows, derived has_more from
that raw fetch, then dropped every row whose stored blob would not parse.
last_id came from the survivors, so a page of corrupt or legacy rows came
back as data [], last_id null, has_more true, and a client following
last_id could not advance. The OpenAI SDK's auto-paginator, which cursors
off the last item in data, stopped silently and returned a truncated list.

Read chunks until page_size + 1 batches survive parsing and file-id
resolution or the caller's rows run out, the way the managed file listing
already does, so a page carries data and a usable cursor while parseable
rows remain and has_more only says true when another one exists. The first
chunk keeps the old page_size + 1 size so a healthy page still costs one
query; a scan that has to continue widens to the file listing's
continuation chunk and stops resolving rows once the page is full.
2026-08-28 07:54:18 -07:00