Fix get_org_id on SaaS + release 0.4.1 - #21
Merged
Conversation
get_org_id only tried GET /ping and /v1/ping, which 404 on the SaaS REST API (api.braintrust.dev). The 0.4.0 oversize-field attachment spilling calls get_org_id() for every row over the per-span limit, so a real migration into SaaS fails: BraintrustAPIError: Unable to determine org_id for attachment operations. Tried /ping and /v1/ping; last error: 404 Not Found for /v1/ping Resolve org_id from a project instead — org_id is a documented top-level field on every Project object (confirmed on both the list and get-by-id responses), and every project visible to an org-scoped API key is in that org: - Capture org_id opportunistically whenever the client lists or creates a project (_maybe_capture_org_id). The orchestrator discovers/creates the dest project before streaming logs, so in the normal flow org_id is already known by the time spilling happens -- no extra request. - get_org_id falls back to GET /v1/project?limit=1 when nothing has been captured yet. Dropped the /ping probes entirely (they only 404 on SaaS). This also fixes the latent copy_attachments path, which had the same get_org_id dependency. Adds get_org_id tests (capture from list/create, query fallback, no-project error) and updates the attachment/spill test mocks to serve /v1/project. Suite: 292. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Doug Guthrie (dpguthrie)
force-pushed
the
fix/org-id-via-project
branch
from
June 8, 2026 19:56
adf374a to
0fbfa64
Compare
Bump version to 0.4.1 (pyproject, __version__, uv.lock), add the CHANGELOG entry for the get_org_id SaaS fix, and update the pinned install command in the README to v0.4.1.
Collaborator
Author
|
Added the 0.4.1 release prep to this PR: CHANGELOG entry, version bump ( Verified the fix end-to-end against live SaaS (seeded a 1.5 MB span, lowered the spill threshold to 1 MB, migrated): the field spilled to a |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A user on 0.4.0 hit this migrating logs into SaaS:
get_org_id()only triedGET /pingand/v1/ping, which 404 on the SaaS REST API (api.braintrust.dev). The 0.4.0 oversize-field attachment spilling callsget_org_id()for every row over the ~20 MB per-span limit, so any real migration with a large span fails. (The SDK resolves org_id viaPOST {app_url}/api/apikey/loginon the app URL, which this tool doesn't use — it only has the API URL.)Fix
Resolve
org_idfrom a project instead.org_idis a documented top-level field on everyProjectobject (confirmed on both the list and get-by-id responses), and every project visible to an org-scoped API key is in that org:_maybe_capture_org_id). The orchestrator discovers/creates the destination project before streaming logs, so in the normal floworg_idis already known by the time spilling happens — no extra request.get_org_idqueriesGET /v1/project?limit=1when nothing has been captured yet./pingprobes entirely — they only 404 on SaaS and add nothing now.Also repairs the latent
copy_attachmentspath, which had the sameget_org_iddependency.Why it holds for the live case: by the time logs are migrated (and spilling), the destination project already exists (created earlier in the run), so its
org_idhas already been captured.Tests
test_get_org_id_captured_from_list_projects/_from_create_project— captured with zero extra requests.test_get_org_id_queries_project_when_not_cached— fallback query.test_get_org_id_raises_when_no_project— clear error./v1/project.Release
Targets a 0.4.1 patch — blocking a live migration. Self-contained off
main(one commit,client.py+ tests); independent of the refactor PR #20.🤖 Generated with Claude Code