Skip to content

fix(settings): preserve OpenAI form input on validation failure#1862

Open
dripsmvcp wants to merge 4 commits into
we-promise:mainfrom
dripsmvcp:fix/1824-preserve-openai-form-input
Open

fix(settings): preserve OpenAI form input on validation failure#1862
dripsmvcp wants to merge 4 commits into
we-promise:mainfrom
dripsmvcp:fix/1824-preserve-openai-form-input

Conversation

@dripsmvcp
Copy link
Copy Markdown

@dripsmvcp dripsmvcp commented May 19, 2026

Summary

Fixes #1824.

The OpenAI settings form (Settings → General → OpenAI) auto-submits on blur. If a user types the URI Base before entering the Model, the partial submission hits the cross-field validation (OpenAI model is required when custom URI base is configured) and the controller re-renders the page. The fields read their value: from Setting.openai_*, which is still blank because the validation prevented the save — so the user's input is silently wiped and they're left staring at an empty field with an error message and no way to recover other than starting over.

This is also the root cause of the symptoms reported in #1825: the auto-submit was persisting partial (URI-base-only or model-only) configs intermittently, which made User#ai_available? return false and locked the AI Chat behind a misleading "set the OPENAI_ACCESS_TOKEN environment variable" message.

What changed

No change to the Setting.validate_openai_config! rule or to any of the existing tests around it (cross-field validation still rejects an incomplete save — we just don't punish the user for it in the UI).

29 LOC across 3 files.

Test plan

  • New regression test preserves submitted openai uri base in form when validation fails fails on main (Expected: "https://api.example.com/v1" Actual: nil) and passes on this branch
  • Existing cannot update openai uri base without model … and cannot clear openai model when custom uri base is set still pass — DB invariants unchanged
  • bin/rails test test/controllers/settings/hostings_controller_test.rb test/models/setting_test.rb — 41 runs, 114 assertions, 0 failures
  • Full bin/rails test — 4307 runs, 0 failures, 26 skips (1 pre-existing env error in active_storage_authorization_test.rb re: missing libvips on local host, reproduces on stock main, unrelated)
  • bin/rubocop -a — clean
  • bundle exec erb_lint app/views/settings/hostings/_openai_settings.html.erb -a — clean
  • bin/brakeman --no-pager — no new warnings
  • Manual: open Settings → General → OpenAI on a self-hosted instance with empty OpenAI config, paste a URL into Base URL, tab out, confirm the URL stays put and the error tells you the model is missing

Summary by CodeRabbit

  • Bug Fixes

    • OpenAI hosting settings form now preserves user-entered OpenAI fields (URI base and model) when validation errors occur, so users can correct issues without retyping submitted values.
  • Tests

    • Added regression tests to verify form input retention after validation failures and prevent future regressions.

Review Change Stack

Before
pr1862-before-bug-openai-section

After
pr1862-after-fix-openai-section
pr1862-after-fix-fullpage

@superagent-security superagent-security Bot added the contributor:verified Contributor passed trust analysis. label May 19, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

Submitting OpenAI hosting settings now preserves user-entered openai_uri_base and openai_model across validation failures: the controller stores submitted values into instance variables and the form partial uses them to re-fill fields on re-render.

Changes

OpenAI Form Input Preservation

Layer / File(s) Summary
Form input preservation on validation error
app/controllers/settings/hostings_controller.rb, app/views/settings/hostings/_openai_settings.html.erb, test/controllers/settings/hostings_controller_test.rb
When Setting::ValidationError is raised during update, the controller stores submitted openai_uri_base and openai_model in @openai_uri_base_input and @openai_model_input. The OpenAI settings partial uses those instance variables (falling back to Setting values) so submitted inputs persist on the re-render; regression tests cover both preservation cases.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

codex

Suggested reviewers

  • matthieuEv

Poem

A rabbit nudges inputs back in place, 🐰
When validation trips and fields may race.
The base and model stay put, not lost,
Re-render keeps what you had crossed.
Small fix, big relief — a tidy case.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'fix(settings): preserve OpenAI form input on validation failure' accurately and concisely describes the main change: preventing form inputs from being lost when validation fails during auto-submit of OpenAI settings.
Linked Issues check ✅ Passed The PR fully addresses issue #1824 by preserving user-submitted OpenAI URI base and model values in form inputs after validation failure, preventing data loss during the auto-submit + cross-field validation workflow.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the issue: controller instance variables stash submitted inputs, view template uses fallback pattern to preserve them on re-render, and tests cover regression scenarios; no unrelated modifications present.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Fixes we-promise#1824.

The OpenAI settings form auto-submits on blur, so typing the URI base
before the model triggers cross-field validation. The rescue re-renders
the page with values read from Setting.openai_*, which is still blank
because the failed save was rejected — so the user's input disappears
and they see 'OpenAI model is required' with no value to fix.

Stash the submitted uri_base and model on rescue and prefer them over
the saved Setting when rendering, so the user can finish typing the
missing field and re-submit.
@dripsmvcp dripsmvcp force-pushed the fix/1824-preserve-openai-form-input branch from 3bdd9d3 to a00fc07 Compare May 19, 2026 14:32
Copy link
Copy Markdown
Collaborator

jjmata commented May 20, 2026

Clean, minimal fix. The instance-variable fallback pattern (@openai_uri_base_input || Setting.openai_uri_base) correctly preserves user input on re-render without affecting the happy path.

The test covers the specific regression scenario well. One small suggestion: it might also be worth a test for the openai_model field symmetrically (entering the model before the URI base), to confirm both directions of the cross-field validation failure preserve the submitted value. The current test only exercises one field.


Generated by Claude Code

@dripsmvcp
Copy link
Copy Markdown
Author

It's been fixed, ty

@superagent-security superagent-security Bot added the pr:verified PR passed security analysis. label May 21, 2026
@dripsmvcp
Copy link
Copy Markdown
Author

@jjmata Would you check it again?

dripsmvcp added 2 commits May 22, 2026 07:29
…e-promise#1862)

jjmata asked for symmetric coverage of the model field. Add a test where
the user changes the URI base and clears the model in the same submit:
the cross-field validation fails and the re-rendered model input must
reflect the submitted (cleared) value rather than reverting to the saved
model. Complements the existing uri_base preservation test.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/controllers/settings/hostings_controller_test.rb (1)

137-140: ⚡ Quick win

Make the assertion more explicit for consistency and robustness.

The current assertion verifies the model field doesn't revert to "saved-model", but it would pass for any other value (empty string, nil, or something unexpected). For clarity and consistency with the uri_base assertion on line 135, explicitly assert the expected cleared value.

✨ Suggested refinement
     assert_select "input[name=?]", "setting[openai_model]" do |inputs|
-      assert_not_equal "saved-model", inputs.first["value"].to_s,
-        "model field must reflect the submitted (cleared) value, not the saved model"
+      assert_equal "", inputs.first["value"].to_s,
+        "model field must reflect the submitted (cleared) value, not revert to the saved model"
     end

This makes the expected behavior explicit and would catch unexpected values beyond just the saved model.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/controllers/settings/hostings_controller_test.rb` around lines 137 -
140, The test currently only asserts the model field is not "saved-model";
change it to assert the exact expected cleared value instead (match the style
used for the uri_base assertion). Locate the assert_select block that references
"input[name=?]", "setting[openai_model]" and replace the negative assertion with
an explicit equality check that inputs.first["value"].to_s equals the expected
cleared value (empty string) so the test fails for nil/unexpected values as
well.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/controllers/settings/hostings_controller_test.rb`:
- Around line 137-140: The test currently only asserts the model field is not
"saved-model"; change it to assert the exact expected cleared value instead
(match the style used for the uri_base assertion). Locate the assert_select
block that references "input[name=?]", "setting[openai_model]" and replace the
negative assertion with an explicit equality check that
inputs.first["value"].to_s equals the expected cleared value (empty string) so
the test fails for nil/unexpected values as well.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c65e95ac-3d1b-4767-b2b2-52401c9c3d5e

📥 Commits

Reviewing files that changed from the base of the PR and between a00fc07 and a00a0d6.

📒 Files selected for processing (1)
  • test/controllers/settings/hostings_controller_test.rb

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

Labels

contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: OpenAI Custom URL field clears itself if Model is not filled first

2 participants