fix(credentials): raise when sentinel placeholder hits an invalid element#797
fix(credentials): raise when sentinel placeholder hits an invalid element#797leo-notte wants to merge 1 commit into
Conversation
WalkthroughThis PR introduces explicit fail-fast behavior for credential placeholder validation. A new Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| Filename | Overview |
|---|---|
| packages/notte-core/src/notte_core/errors/processing.py | Adds CredentialFieldValidationError with well-structured dev/agent/user messages; no issues found |
| packages/notte-core/src/notte_core/credentials/base.py | Replaces silent trace log with a CredentialFieldValidationError raise in the non-FormFillAction validation path; logic is correct |
| packages/notte-browser/src/notte_browser/session.py | Adds dedicated except CredentialFieldValidationError: raise guard before the broad except ValueError to prevent the error from being swallowed |
| tests/test_session_vault_helpers.py | 4 new unit tests covering the error path, happy path, asymmetric username behaviour, and session-level propagation; no integration tests added |
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:115-190
**Missing integration test for a bug-fix PR**
The four new tests all use `MockVault` and `make_snapshot`, so they exercise only the in-process logic. Per the project's test guidelines, every bug-fix PR should include at least one integration test. The reported repro (target a label element on a real page with a live vault entry) is a good candidate — without it, a regression that re-introduces the silent no-op would not be caught automatically.
- Add a comment if the PR does n... ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))
Reviews (2): Last reviewed commit: "fix(credentials): raise when sentinel pl..." | Re-trigger Greptile
…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>
4182b8e to
52fbcdb
Compare
There was a problem hiding this comment.
LGTM
No new issues introduced. The code and tests are correct and unchanged from the previous LGTM review.\n\nCI Failures: tests/test_trajectory.py::test_agent_observes_page_correctly failed with LLMParsingError — this is a flaky test that hits a live LLM and is unrelated to this PR's credential changes. Tracked in insight 01KRYWT00XT4JW0PFNHS8Y7KEN.
Tag @mendral-app with feedback or questions. View session
|
@greptileai review |
Summary
When a known credential sentinel (e.g.
PASSWORD = "mycoolpassword"fromnotte_core.credentials) was supplied for aFillActionbut the targeted element failed the credential field'svalidate_elementcheck,replace_credentialssilently 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_elementreturnsTrueunconditionally → username substitution proceeded.PasswordField.validate_elementrequiresattrs.type == "password"→ password substitution silently no-op'd while the fill itself reported success.End result:
mycoolpasswordgot typed into the password field as plaintext and the user only noticed because they manually re-read.valueviaeval-js.Changes
notte_core.errors.processing: newCredentialFieldValidationError(NotteBaseError)with dev/agent/user messages naming the placeholder, credential key, and offending element attrs.notte_core.credentials.base.replace_credentials: replaces the silentlogger.tracewith a raise. The branch only fires when the value already matched a known sentinel (lines 658–661 still raiseInvalidPlaceholderErrorfor 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 dedicatedexcept CredentialFieldValidationError: raiseahead of the broadexcept ValueError, otherwise the new error would be swallowed (sinceNotteBaseErrorextendsValueError).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
validate_element(username unconditionally accepts, password requirestype=="password") is preserved — pinned by the newtest_username_placeholder_unaffected_by_validation_change. Tightening username validation would be a separate behavioural change.LocatorAttributeswould 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)notte page fill M2 mycoolpasswordonthe-internet.herokuapp.com/loginwith a vault entry) and confirm the call now raises instead of silently typingmycoolpasswordinto the password field🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Note
Replaces a silent
logger.traceno-op inreplace_credentialswith a newCredentialFieldValidationErrorwhen a known credential sentinel targets an element that failsvalidate_element. Adds a dedicatedexcept CredentialFieldValidationError: raisein_action_with_vaultto prevent the broadexcept ValueErrorfrom swallowing it. Four new tests cover the error path, happy path, asymmetric username behaviour, and session-level propagation.Written by Mendral for commit 52fbcdb.