Skip to content

fix(auth): point users with a valid key to the license acceptance page (ENG-886) - #1340

Open
eddiebergman-priorlabs wants to merge 7 commits into
mainfrom
eddie/eng-886-better-error-message-in-tabpfn-when-token-is-present-but
Open

eddiebergman-priorlabs wants to merge 7 commits into
mainfrom
eddie/eng-886-better-error-message-in-tabpfn-when-token-is-present-but

Conversation

@eddiebergman-priorlabs

@eddiebergman-priorlabs eddiebergman-priorlabs commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

tldr; ended up re-organizing as it was a bit chaotic with nested if and overloaded meaning of None. Also fixes a potential issue where token is for an account, other than the one that is logged in. This could lead to a potentially frustrating exp. where the user could accept the license for their account, but perhaps be using some org shared token or otherwise.


Motivation and Context

People create an API key, set TABPFN_TOKEN, and forget to accept the model license. TabPFN sees that the key is valid and the license is not accepted, so it tries to open the browser. That can't happen in a notebook without a TTY, in CI, in an agent, or with TABPFN_NO_BROWSER set, so it raises the generic error telling the user to log in, copy an API key and set TABPFN_TOKEN. They already did that, and the message doesn't say what is missing.

Now, when the cached key is valid, the license is not accepted, and browser login can't run, the error says the user is logged in but hasn't accepted the license, and links to <gui>/accept-license?hf_repo_id=<model>. The existing error for a browser login that ends without acceptance uses the same message.

When a browser is available and the key is valid, TabPFN now opens <gui>/accept-license?hf_repo_id=<model>&callback=... directly instead of the full login. Without a display there is nothing to paste, since the key is already set, so it raises the error with that link. If the browser isn't signed in, the web app takes the user through login and back to the acceptance page. If the browser is signed in to a different account than a TABPFN_TOKEN key, acceptance would land on the wrong account and every later run would reopen the browser. TabPFN now re-checks the key the next run will use and says so.

The outcomes are now one exhaustive match on two things: what is missing (_AuthStep.LOGIN or _AuthStep.ACCEPT_LICENSE), and why the browser produced no key (_NoBrowserToken.DISABLED or UNAVAILABLE). The valid-key case no longer sets token to None, and mypy flags any combination that isn't handled.

Public API Changes

  • No Public API changes

How Has This Been Tested?

Added test_browser_is_asked_for_the_missing_step (a valid key asks only for acceptance; no key asks for login), plus tests that the graphical flow opens /accept-license for the acceptance step, that the headless flow defers to the error with that link, and that acceptance in a different browser account raises for a TABPFN_TOKEN key but just works for a cached key. Also added test_valid_token_without_license_links_to_acceptance to tests/test_browser_auth.py, parametrized over browser disabled, browser unavailable, and a browser login that ends without acceptance. The first two failed on main with the generic message and pass now. The disabled case also checks that no browser is opened. The rest of tests/test_browser_auth.py passes, as does pre-commit (ruff, mypy).

Checklist

  • The changes have been tested locally.
  • A changelog entry has been added.
  • The code follows the project's style guidelines.
  • I have considered the impact of these changes on the public API.

🤖 Generated with Claude Code

eddiebergman-priorlabs and others added 3 commits October 1, 2026 14:11
…e (ENG-886)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in tests (ENG-886)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eddiebergman-priorlabs
eddiebergman-priorlabs marked this pull request as ready for review October 1, 2026 12:22

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread src/tabpfn/browser_auth.py Outdated
Comment thread src/tabpfn/browser_auth.py Outdated
if no_browser and no_browser not in ("0", "false", "no", "off"):
browser_disabled = no_browser and no_browser not in ("0", "false", "no", "off")
token = None if browser_disabled else try_browser_login(gui_url, hf_repo_id)
if token is None and has_token_without_license:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case browser_disabled is true & user has a valid token, but just didn't accept the license, wouldn't a better path be directing user to accept the license without setting token to None?

eddiebergman-priorlabs and others added 3 commits October 1, 2026 16:33
With a valid API key and an unaccepted license, the browser flow now goes
straight to the license acceptance page instead of the full login. The
outcomes are spelled out as an exhaustive match over what is missing (login
or acceptance) and why the browser produced no key (disabled or unavailable),
so the valid-key case no longer relies on resetting the token to None.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The browser may be signed in to another account than the API key. A
TABPFN_TOKEN key outranks the saved browser key, so every later run would
reopen the browser without saying why. Re-check the key the next run will
use and explain the mismatch.

Without a display, a valid key no longer asks for a key to paste; the error
links to the acceptance page. Browser URLs and the acceptance link now come
from one helper, and the helpers take required keyword arguments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64b5353. Configure here.

Comment thread src/tabpfn/browser_auth.py
Comment thread changelog/1340.fixed.md Outdated
A rejected TABPFN_TOKEN survives the cache cleanup, so after a normal login
the re-check saw it and wrongly reported a different account. Only the
acceptance step started from a verified key, so limit the check to it. Also
shorten the changelog entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants