Skip to content

fix(credentials): raise when sentinel placeholder hits an invalid element#797

Open
leo-notte wants to merge 2 commits into
mainfrom
fix/raise-on-credential-validation-failure
Open

fix(credentials): raise when sentinel placeholder hits an invalid element#797
leo-notte wants to merge 2 commits into
mainfrom
fix/raise-on-credential-validation-failure

Conversation

@leo-notte
Copy link
Copy Markdown
Contributor

@leo-notte leo-notte commented May 4, 2026

Summary

When a known credential sentinel (e.g. PASSWORD = "mycoolpassword" from notte_core.credentials) was supplied for a FillAction but the targeted element failed the credential field's validate_element check, replace_credentials silently logged at trace level and returned the action unmodified — causing the literal placeholder string to be typed into the form.

This was easy to hit by targeting a <label> rather than its associated <input type="password"> (e.g. via observe IDs that point at the label):

  • UserNameField.validate_element returns True unconditionally → username substitution proceeded.
  • PasswordField.validate_element requires attrs.type == "password" → password substitution silently no-op'd while the fill itself reported success.

End result: mycoolpassword got typed into the password field as plaintext and the user only noticed because they manually re-read .value via eval-js.

Changes

  • notte_core.errors.processing: new CredentialFieldValidationError(NotteBaseError) with dev/agent/user messages naming the placeholder, credential key, and offending element attrs.
  • notte_core.credentials.base.replace_credentials: replaces the silent logger.trace with a raise. The branch only fires when the value already matched a known sentinel (lines 658–661 still raise InvalidPlaceholderError for unknown values), so raising here is the correct signal: the caller clearly intended a substitution and the literal sentinel must not leak into typing.
  • notte_browser.session._action_with_vault: adds a dedicated except CredentialFieldValidationError: raise ahead of the broad except ValueError, otherwise the new error would be swallowed (since NotteBaseError extends ValueError).
  • tests/test_session_vault_helpers.py: 4 new tests covering the new raise, the happy substitute path, the asymmetric username path, and propagation through the session-level catch.

Out of scope

  • The asymmetric design of validate_element (username unconditionally accepts, password requires type=="password") is preserved — pinned by the new test_username_placeholder_unaffected_by_validation_change. Tightening username validation would be a separate behavioural change.
  • Resolving label → associated input before reading LocatorAttributes would also fix the reported case but is a larger refactor; the raise is the safer first step because it surfaces the failure instead of corrupting the field.

Test plan

  • pytest tests/test_session_vault_helpers.py — 8 passed (4 existing + 4 new)
  • Manual: rerun the original repro (notte page fill M2 mycoolpassword on the-internet.herokuapp.com/login with a vault entry) and confirm the call now raises instead of silently typing mycoolpassword into the password field

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Credential replacement now fails fast with clear validation errors when a placeholder targets an invalid field, preventing silent failures.
  • Tests
    • Added tests covering credential placeholder validation and error propagation.
  • Documentation
    • API docs updated to include a new "POST Search Web" entry in the Search section.

Note

Replaces a silent logger.trace no-op in replace_credentials with a new CredentialFieldValidationError when a known credential sentinel targets an element that fails validate_element. Adds a dedicated except CredentialFieldValidationError: raise in _action_with_vault to prevent the broad except ValueError from swallowing it (since NotteBaseError extends ValueError). Four new tests cover the error path, happy path, asymmetric username behaviour, and session-level propagation.

Written by Mendral for commit ef6c490.

…ment

When a known credential sentinel (e.g. PASSWORD = "mycoolpassword") was
supplied for a fill action but the targeted element failed the field's
validate_element check, replace_credentials silently logged at trace and
returned the action unmodified — causing the literal placeholder string
to be typed into the form. This was easy to hit by targeting a <label>
instead of its associated <input type="password">: UserNameField
validates True unconditionally, so username substitution worked, but
PasswordField requires attrs.type == "password", so password
substitution silently no-op'd while the fill itself appeared to succeed.

Replace the silent skip with a new CredentialFieldValidationError. Also
add a dedicated except in NotteSession._action_with_vault so the broad
`except ValueError` (which would otherwise swallow it via NotteBaseError)
doesn't suppress the new error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b848f3a6-bef5-4194-8b47-38f757180d2e

📥 Commits

Reviewing files that changed from the base of the PR and between ef6c490 and 4182b8e.

📒 Files selected for processing (1)
  • docs/src/llms.txt
✅ Files skipped from review due to trivial changes (1)
  • docs/src/llms.txt

Walkthrough

A new exception, CredentialFieldValidationError, was added to errors/processing and is raised by BaseVault.replace_credentials when a credential placeholder targets an element that fails the field’s validate_element check. The browser session now explicitly imports and re-raises CredentialFieldValidationError in _action_with_vault rather than treating it like a generic ValueError. Tests were added to assert that password placeholders on invalid elements raise the new error, valid password inputs substitute correctly, username placeholders remain substitutable, and the session layer propagates the validation error.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: raising an exception when a credential sentinel placeholder targets an invalid element, which is the core fix across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/raise-on-credential-validation-failure

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 4, 2026

Greptile Summary

This PR fixes a silent credential-leak bug where a PasswordField sentinel passed to FillAction targeting a non-password element (e.g. a <label>) would silently no-op and type the literal placeholder string into the field. The fix replaces the logger.trace no-op with a CredentialFieldValidationError raise, adds a dedicated re-raise in the session-level ValueError catch to prevent swallowing, and covers all new paths with unit tests.

Confidence Score: 4/5

Safe to merge; the logic is correct and well-tested at the unit level, with the only gap being a missing integration test required by repo policy.

All P2 findings — the implementation is sound and the except CredentialFieldValidationError: raise ordering correctly prevents the new error from being swallowed by the broad except ValueError. Score stays at 4 due to the missing integration test required by the custom rule for bug fix PRs.

tests/test_session_vault_helpers.py — needs an integration test against a real browser/vault to satisfy repo policy.

Important Files Changed

Filename Overview
packages/notte-core/src/notte_core/errors/processing.py New CredentialFieldValidationError class with dev/agent/user messages; well-structured, consistent with existing error classes.
packages/notte-core/src/notte_core/credentials/base.py Silent logger.trace replaced with raise CredentialFieldValidationError in the sentinel-validation-failure branch; correctly scoped to only the LLM-chosen element path (not the regex/FormFill path).
packages/notte-browser/src/notte_browser/session.py Adds except CredentialFieldValidationError: raise ahead of the broad except ValueError to prevent the new error (a ValueError subclass) from being silently swallowed.
tests/test_session_vault_helpers.py 4 new unit tests covering the error raise, happy path, asymmetric username design, and session-level propagation; no integration test against a real browser/vault as required by repo policy for bug fix PRs.

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
tests/test_session_vault_helpers.py:80-150
**Missing integration test for a bug fix PR**

The four new tests all use `MockVault` and a stubbed locator — they never exercise a real browser or real vault. Per the repo's test policy, every bug fix PR should include at least one integration test. The original repro (`the-internet.herokuapp.com/login` with a live vault entry) is listed in the test plan but remains unchecked, and the issue was only discovered because a user manually inspected `.value` via `eval-js`. An integration test that drives a real password field with a vault-backed sentinel would guard against regressions where the locator resolution silently returns a wrong element type again.
- Add a comment if the PR does n... ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))

Reviews (1): Last reviewed commit: "fix(credentials): raise when sentinel pl..." | Re-trigger Greptile

mendral-app[bot]

This comment was marked as outdated.

The docs-sdk-generate pre-commit hook was failing CI because the upstream
OpenAPI spec at api.notte.cc gained a Search Web endpoint that wasn't
reflected in the committed llms.txt. Regenerate to clear the hook.

Co-Authored-By: Claude <noreply@anthropic.com>
@2027-evals
Copy link
Copy Markdown

2027-evals Bot commented May 4, 2026

🌊 Waiting for deployment on commit 4182b8e to finish...

Detected prompts matching nottelabs/notte:

Getting Started — current: no baseline yet · View metrics

Prompt text:

Use Notte to run a headless browser session. Follow the quickstart at https://notte.cc/ to set up a project that:

  1. Creates a cloud browser session
  2. Connects to it using Playwright, Puppeteer, or the Notte SDK
  3. Navigates to https://news.ycombinator.com
  4. Extracts the titles of the top 5 stories
  5. Prints them to stdout

Evaluating agent experience using 2027.dev · View dashboard

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.

1 participant