Commit graph

639 commits

Author SHA1 Message Date
yuneng
ff6578183b test(e2e): align completion, SAIL, and spend-log fixtures with supported contracts (#43902)
Partial backport to stable/1.103.x: only the text completion endpoint test moves off the retired gpt-3.5-turbo-instruct to openai/gpt-5.4-nano with reasoning off. This line predates the OpenAI SDK rewrite of the test, so reasoning_effort goes through EndpointsClient.text_completions instead of extra_body. The SAIL, spend-log and coverage registry repairs are not needed for this line's e2e suite

(cherry picked from commit e61733b170)
2026-10-03 21:07:17 +00:00
yuneng
3896240d3b test(ci): repair stale tests and flaky CI infrastructure (#43983)
Partial backport to stable/1.103.x: only the Together AI structured-output e2e case moves to the hybrid reasoning backend with reasoning off, since the reasoning-only model it picked returned no content. The CI infrastructure and other test repairs are not needed for this line's e2e suite

(cherry picked from commit 6ca90b927c)
2026-10-03 21:07:17 +00:00
Yuneng Jiang
a80eacacee
refactor(auth): bind UI/CLI session tokens to their own AES-GCM context
Backport of BerriAI/litellm-private#5 (12981f93d3) onto stable/1.103.x, applied as
the PR's net diff so main-only intermediate refactors stay out.
2026-09-29 15:17:24 -07:00
yuneng-jiang
cc111d1ae5
fix(streaming): backport text-completion usage fix and e2e provider-flake tolerance to rc/1.103.0 (#43400)
* test(e2e): tolerate provider-side flakes on five full-suite cells (#42628)

* test(e2e): tolerate provider-side flakes on five full-suite cells

Mistral OCR retries a provider-relayed 429 with backoff, the Vertex vision
probe turns reasoning off so its 32 tokens go to the answer, the Vertex
cache cell spaces eight never-seen prefixes 15s apart around Google's
nondeterministic minimum-token rejection and prices the cached tokens
instead of prompt_tokens, and the Azure content-policy cell resends the
jailbreak prompt while Azure skips its filter

* test(e2e): shorten the new helper docstrings

* test(e2e): accept a relayed provider 429 on the rust OCR cells

The gateway already retries a provider 429 three times per call and the
Mistral key is shared across pipelines, so a throttle can hold across all
four attempts of the OCR cell. After the bounded retries the cell now
accepts the gateway's faithful relay of the provider's 429 (throttling_error,
code 429) as its second expected outcome; the gateway's own 429 and any
other error still fail the cell at once.

* test(e2e): drop the harness unit tests, the live cells cover the helpers

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
(cherry picked from commit 41ca4656cd)

* fix(streaming): keep litellm Usage on text-completion usage chunks (#43047)

* fix(streaming): keep litellm Usage on text-completion usage chunks

* fix(streaming): convert provider usage to litellm Usage instead of dropping it

(cherry picked from commit be35b22dfc)

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-26 19:12:06 -07:00
yuneng-jiang
4dbbe6eddd
test(ci): fix the e2e and integration reds left on rc/1.103.0 after #43382 and #43388 (#43391)
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled
The batch cleanup leftover warning used a class defined in a test-directory module. The xdist controller cannot import it, so an uncaught leftover warning crashed the whole e2e run. It is now a plain UserWarning.

The integration harness backport missed the workers option and Gateway.request headers that the OTel conversation id tests use.
2026-09-26 17:54:12 -07:00
yuneng-jiang
8aca86a571
test(e2e): clear the two rc/1.103.0 e2e reds owned by upstream providers (#43388)
Backports the batch cleanup half of #43321 so an Azure cancel still in progress after 120s leaves a warning instead of a teardown error, and points the MCP Tools UI test at DeepWiki's renamed ask_wiki_question tool.
2026-09-26 17:18:10 -07:00
yuneng-jiang
6076c0a058
fix(jwt,otel): backport session conversation id and JWT team header selection to rc/1.103.0 (#43343)
* feat(otel): emit gen_ai.conversation.id from the caller's session id on v2 LLM spans (#42486)

* feat(otel): emit gen_ai.conversation.id from the caller's session id on v2 LLM spans

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): keep the caller's header session under missing_session_id: generate and read replayed payload session ids

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): drop only the proxy-minted session id so a caller id on the other metadata key survives

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): keep a replayed session id hidden when it only echoes the payload trace id

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): keep a replayed session id even when the payload trace id fell back to it

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): stop reading the replayed payload's session id, the generated marker does not survive replay

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(integration): audit gen_ai.conversation.id on otel v2 spans through a real proxy, sink and postgres

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(integration): keep otel conversation rigs alive for the whole session so shuffled shards do not reboot the proxy per test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(otel): stop the audit rig proxies from probing sibling test peers for model info

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(otel): record accepted OTLP batches in the sink instead of mutating the collector

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(otel): guard the accepted batch deque so snapshots cannot race sink appends

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: mrinal <mrinal@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: yucheng <yucheng@berri.ai>
(cherry picked from commit a3196907e4)

* fix(jwt): accept a team alias in x-litellm-team-id (#42445)

* fix(jwt): accept a team alias in x-litellm-team-id

The header only matched canonical team ids, so a JWT caller selecting one of their teams by its alias got a 403 even though they belonged to it. The header value is now resolved through the existing alias lookup before the JWT allowed-team check and the DB membership fallback, while a value that is already a team id never costs an alias lookup and denials keep naming the value the caller sent

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(jwt): only alias a header team id the database provably lacks

Under fallback_to_db_teams a header value whose team row read fails for any reason other than TeamNotFoundError now keeps the membership denial instead of falling through to the alias lookup, so a degraded read cannot select a different team that carries the value as an alias. Drops the HeaderTeam docstring that only restated its fields

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 071cb49d32)

* fix(jwt): say x-litellm-team-id matched no team id or alias in the 403 (#42495)

* fix(jwt): say x-litellm-team-id matched no team id or alias in the 403

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(jwt): tell the caller when x-litellm-team-id names an alias shared by several teams

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(jwt): deny a shared x-litellm-team-id alias exactly like an unknown value

A distinct 403 for an alias several teams share was raised before the
allowed-teams check, so any JWT could probe which aliases exist. The
alias lookup now treats the duplicate as a miss, and both denials say
the value does not resolve to a team id or a unique team alias, which
is true for unknown, unauthorized and duplicate values alike

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 08639fcf42)

* fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim (#43206)

* fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* docs(jwt): describe header team selection under fallback_to_db_teams

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 7b4fd47c6e)

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mrinal <mrinal@berri.ai>
Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: yassin <yassin@berri.ai>
2026-09-26 15:03:25 -07:00
Yuneng Jiang
379d256eb9
test(batches): skip the Bedrock GovCloud batch e2e until its secrets are provisioned
The test resolves four AWS_GOVCLOUD_* values through os.environ/ references on
the deployment, and none of them is injected into the e2e stack, so the upload
returns 500 "S3 bucket_name is required" and the test fails on configuration
rather than on the GovCloud partition behavior it guards.

The runner podSpec mounts 29 individual secretKeyRef entries from
litellm-provider-keys with no envFrom, and the string "govcloud" appears
nowhere in project-releaser, so nothing supplies these values today. The
commercial-partition Bedrock batch tests resolve their own os.environ/ bucket
and pass, which rules out the reference syntax and leaves the absent secrets as
the only cause.

Skipped rather than weakened, matching the LIT-5027 and LIT-4820 markers in
this file: the assertions stay as the correct contract and the marker names the
condition for removing it.

Reports 1 skipped instead of 1 failed.
2026-09-19 19:55:07 -07:00
Yuneng Jiang
9f84382a24
test(e2e): cite the source and date for the pinned Nova Sonic model id
AGENTS.md allows a vendor-owned literal only when its source and date are cited
next to it. A live realtime test cannot avoid naming a model, so record how the
id was checked, and record that a retired id fails as a hang rather than an
error so the next reader does not start by suspecting litellm.
2026-09-19 17:20:00 -07:00
Yuneng Jiang
ca18755b64
test(e2e): point the Nova Sonic realtime test at nova-2-sonic
AWS retired amazon.nova-sonic-v1:0. GetFoundationModel now answers
ResourceNotFoundException "This model version has reached the end of its life",
and opening a bidirectional stream against it fails with ValidationException
"The provided model identifier is invalid". amazon.nova-2-sonic-v1:0 is the
active replacement.

The test passed on builds 219 (2026-09-16) and 246 (2026-09-17) and has failed
every run since, three attempts per build, with no litellm change to the
realtime path in between. The symptom was a clean websocket close: Bedrock ends
the stream rather than erroring, the forwarder treats a None receive as a normal
stream end and closes the client socket, so the client sees ConnectionClosedOK
and the test fails waiting for response.done.

litellm already carries both models in the cost map, with
"deprecation_date": "2026-09-14" on the old one, and the promptStart
transformation already sends the audioOutputConfiguration that nova-2-sonic
requires; only the test constant was left behind.

Verified against live Bedrock with the promptStart shape the transformation
builds: amazon.nova-sonic-v1:0 raises "The provided model identifier is
invalid", amazon.nova-2-sonic-v1:0 opens a session and returns a usageEvent.

The mocked handler and provider-cache tests keep the old id: it is only a label
there, no call reaches AWS.
2026-09-19 16:55:00 -07:00
Mateo Wang
af6a1798e2
Revert "test(e2e): cover MCP OAuth SSO and cold restart persistence" 2026-09-19 16:15:43 -07:00
Mateo Wang
0058e1554b
Merge pull request #41909 from BerriAI/litellm_mcp_oauth_happy_path_e2e
test(e2e): cover MCP OAuth SSO and cold restart persistence
2026-09-19 16:08:51 -07:00
Mateo Wang
7651d6b550
Merge pull request #41942 from BerriAI/litellm_vllm_batch_runner
feat(batches): run hosted_vllm batches inside LiteLLM
2026-09-19 15:44:26 -07:00
Joshua Valluru
31b4405435 chore: merge main with shared E2E lockout fix 2026-09-19 15:10:55 -07:00
Joshua Valluru
90687ae597 test(e2e): detect fast upstream reauthorization on reconnect 2026-09-19 14:39:03 -07:00
Joshua Valluru
742a3ad93d ci(e2e): trigger OAuth acceptance on relevant pull requests 2026-09-19 13:30:36 -07:00
Joshua Valluru
b7bab56d4d test(e2e): report safe OAuth failure locations 2026-09-19 12:52:28 -07:00
Yuneng Jiang
bf9c717d77
test(e2e): stop the config suite locking itself out of the shared proxy
Two tests in the config/misc management suite were failing every run against
the Buildkite e2e stack, and one of them took the rest of the build with it.

test_add_allowed_ip_does_not_store_unrelated_config_value posted 127.0.0.1 to
/add/allowed_ip. That route sets the live general_settings["allowed_ips"] that
auth_utils._check_valid_ip reads before it persists anything, and the check is
exact string membership with no CIDR support, so from the moment the POST
returns only 127.0.0.1 can reach the proxy. The runner 403s on its very next
call, and the deferred /delete/allowed_ip sits behind the same auth dependency,
so the cleanup is locked out too and every later test in the build 403s. Build
254's first attempt lost 459 of its 465 failures to that one cascade.

There is no safe way to exercise the route against a shared proxy: nothing
reports the caller's address as the proxy sees it, so a test cannot allowlist
itself first. Move the claim to the route's own TestClient suite, where the
auth dependency is overridden and general_settings is per-test, and record the
route in the module docstring beside /cache/settings and the Vault override so
it is not re-added. save_config's end of the contract was already covered by
test_ProxyConfig_save_config_merges_changed_keys_without_copying_file_settings;
the new test covers the route's end, that what it hands save_config differs
from the loaded config in allowed_ips and nothing else.

The unrelated-key probe also only ever worked on one lane: max_parallel_requests
was added to tests/e2e/gateway/stage_mirror_ci_config.yml and never to the
Buildkite stack's config, where resolve() reports it as "unset" rather than
"config". That key is now unused, so drop it again.

test_config_update_persists_router_setting_to_get wrote router_settings.
num_retries, which both lanes declare in their config file, so the config-
ownership work correctly refuses it with a 400. Switch to retry_after, which is
declared by neither lane, is accepted by /config/update, and is reported back by
GET /router/settings. Verified against a live proxy: max_fallbacks also takes
the write but never reads back, so the read-back poll is what picks the key.
2026-09-19 12:51:54 -07:00
Joshua Valluru
4e8a4d4b61 test(e2e): restore existing OAuth chat test to baseline 2026-09-19 12:17:51 -07:00
Devin AI
8f8c2e2fda ci(e2e): keep the Linear OAuth chat test out of the stage-mirror selector
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 19:13:44 +00:00
Joshua Valluru
09a2e5b6ec test(e2e): adapt OAuth acceptance to merged SDK2 2026-09-19 11:59:29 -07:00
mateo-berri
fd45412c89 feat(batches): run hosted_vllm batches inside LiteLLM
vLLM serves no /v1/files or /v1/batches, so a hosted_vllm deployment can never
host a batch. Batch inputs for such a deployment now land in a LiteLLM-owned
storage backend, the batch is executed line by line through the deployment's
own chat, completion, embedding, or responses route, and the batch plus its
output and error files are served back from the database under the creating key
2026-09-19 01:47:43 -07:00
Devin AI
fdb0fb648e fix(e2e): bind MCP OAuth acceptance to the owned gateway and snapshot the stored token once per phase
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 08:12:35 +00:00
Joshua Valluru
f5ab563499 fix(mcp): preserve session expiry signals and scope dependency CI 2026-09-18 22:52:10 -07:00
Joshua Valluru
7f4dd4eabc test(e2e): cover MCP OAuth SSO and cold restart acceptance 2026-09-18 22:02:09 -07:00
Devin AI
62051ad9bc merge: bring main into litellm_mcp_oauth_happy_path_e2e
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 03:42:37 +00:00
Yujong Lee
bf7d1c0733 chore: consolidate CLAUDE.md into AGENTS.md
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 02:30:35 +00:00
Devin AI
ebf3f04717 test(e2e): shorten the Linear tool citation
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 02:03:43 +00:00
Devin AI
fc4a11ac53 test(e2e): call the prefixed tool, require two gateways, cite the Linear tool name
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 02:03:12 +00:00
Devin AI
890e5feabe test(e2e): keep e2e_config formatting untouched
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 00:38:57 +00:00
Devin AI
c1bd5ba91d test(e2e): share the Linear readonly tool constant and fail fast on unexpected consent
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 00:38:28 +00:00
Devin AI
6c8f1c22e0 test(e2e): cover MCP OAuth happy path through gateway
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 00:35:56 +00:00
joshua
7410d00d2e merge(main): resolve mcp server.py import conflict and relock
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 00:08:33 +00:00
joshua
8d8efe7203 style(mcp): satisfy lint and type budgets for the SDK 2 port
Format the ported files, annotate mutable wire payloads, give the e2e
OAuth client the SDK 2 httpx2/AuthorizationCodeResult API, tighten the
transport-streams alias to the two-stream SDK 2 shape, and add a
test-quality reason for the MockTransport factory injection.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-18 23:49:23 +00:00
Yuneng Jiang
0d9c5159df
test(e2e): assert config ownership instead of absence from the stored row
/config/field/info used to answer from the LiteLLM_Config row, so "the field
400s" proved the row did not carry it. It now answers from the resolved
settings, and the CI stack config declares general_settings.max_parallel_requests,
so the endpoint returns that value and the old assertion could never hold.

The check that /add/allowed_ip writes only what the caller changed moves to
/config/list, which still reports stored_in_db off the row, and the field/info
call now asserts the ownership the endpoint reports: the config file owns the
key, so it reads back as source=config and editable=false.

Verified against a live proxy on an isolated Postgres rather than in CI, where
this check has never run: it waits on protected-environment approval.
2026-09-18 02:53:37 -07:00
Yuneng Jiang
8e67a33fc3
fix(proxy): refuse config-owned writes at one choke point and refresh the store
Both write paths now go through the same refusal, so /config/field/update and
/config/update answer identically instead of each phrasing its own rule.

A successful write now applies to the SettingsStore, so the next read sees it.
Without this, /config/field/info reported a key the dashboard had just stored
as "not set" until the process reloaded from the database.

resolve() no longer takes a KeyRule it never reads; the store picks the row.
The matrix tests resolve through SettingsStore instead of calling resolve
directly, so the section and key in each case actually route a lookup.

ConfigFieldInfo and ConfigList type `source` as the FieldSource literal, and
the dashboard API types are regenerated for the two new fields.
2026-09-18 01:49:30 -07:00
yuneng-jiang
fc49ad7042
Merge pull request #41748 from BerriAI/litellm_wt_0917_7e12
fix(proxy): persist only the keys a caller changed in save_config
2026-09-17 22:57:06 -07:00
Yuneng Jiang
593fa5921a
test(e2e/ui): wait for the filtered budget list before clicking a row action
All three budget specs searched by typing into the search box and moved on
immediately. The search is debounced 300ms, and while the filtered query is in
flight react-query serves the previous page as placeholder data, which the list
hook reports as isLoading, which makes the table swap its whole body for
skeleton rows.

So the row assertion passed against the pre-search rows, and roughly 300ms later
the skeleton swap unmounted the row the spec had just opened the action menu on.
Playwright logged "element is not stable" twice and then "element was detached
from the DOM", and since the menu never reopened the click burned the full 15s
action timeout on all three attempts. Losing that race was pure timing: build
386 and build 387 of the UI suite ran the same commit 4b368bf066, and 386
passed where 387 failed on this spec plus "Delete a budget"

searchForBudget now waits for the GET that carries q=<budget id>, matching what
projectDetachment.spec.ts already does for a key search. That also gives the row
assertion something real to assert, since until now it could pass without the
search having filtered anything
2026-09-17 21:39:22 -07:00
Yuneng Jiang
af17691389
fix(proxy): persist only the keys a caller changed in save_config 2026-09-17 20:32:04 -07:00
kerry
bbde2f8a3a docs(e2e): name the govcloud env vars in the coverage matrix row
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 22:07:50 +00:00
kerry
bdd9335116 docs(e2e): list the govcloud bedrock test as a coverage matrix row
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 21:51:02 +00:00
kerry
4b45fd5f44 docs(e2e): drop govcloud keys from the contributing starter env
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 21:47:21 +00:00
kerry
5aec6d7bb6 test(e2e): assert govcloud file content round-trips the uploaded record
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 21:31:33 +00:00
kerry
435ab2ccc0 Merge remote-tracking branch 'origin/main' into litellm_aws_govcloud_partition_gate 2026-09-17 20:16:28 +00:00
kerry
5a5b18550c test(e2e): cover bedrock batch files in govcloud
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:16:09 +00:00
joshua-berri
f075417643
Merge pull request #41609 from BerriAI/litellm_fix_mcp_health_permissions_4504
fix(mcp): restrict health discovery to virtual key grants
2026-09-17 19:03:50 +00:00
Yujong Lee
b26935416a Merge remote-tracking branch 'github/main' into litellm_rust_bridge_declarative_route_catalog
# Conflicts:
#	tests/e2e/access_control/test_model_access_group_e2e.py
2026-09-17 11:08:08 -07:00
Yujong Lee
56ba988b62 fix wrong assertion 2026-09-17 10:54:58 -07:00
Yuneng Jiang
dd6ef9e1bc
fix(e2e): delete raw cloud-storage batch files with the master key
DELETE /v1/files/{id} only lets a proxy admin key delete a raw s3:// or
gs:// file id, because such ids skip the managed-file owner check. The
batch lifecycle cleanup deleted the vertex_ai raw ids with the test's
own virtual key and got a 403 at teardown on every build since #194

Raw cloud-storage ids now go through the master key; managed and
provider-native ids keep using the creating key
2026-09-17 10:37:08 -07:00
Yuneng Jiang
1d71564063
fix(e2e): settle the team allow-list through /team/info
The team access-group fixture polled a 403 until its message enumerated
the team's allow-list, because registering a team-scoped deployment
appends that deployment to the list and the fixture has to wait for the
reset to land. #41310 replaced that message with a fixed client-facing
one, so the poll never matched and both tests errored at setup

The allow-list is now read back from /team/info until it holds exactly
the access group
2026-09-17 10:37:07 -07:00