Skip to content

Add "client.showErrorLinks` config option (#11238)"#13472

Merged
sfc-gh-lwilby merged 11 commits intostreamlit:developfrom
karubian:feature/disable-exception-links
Jan 28, 2026
Merged

Add "client.showErrorLinks` config option (#11238)"#13472
sfc-gh-lwilby merged 11 commits intostreamlit:developfrom
karubian:feature/disable-exception-links

Conversation

@karubian
Copy link
Copy Markdown
Contributor

Describe your changes

Adds a new client.showExceptionLinks config option that allows users to disable the Google/ChatGPT help
links shown in exception displays on localhost.

When set to false in .streamlit/config.toml:
toml
[client]
showExceptionLinks = false

The external help links (Copy, Ask Google, Ask ChatGPT) will be hidden from exception messages.

This addresses privacy and security concerns for companies that prohibit ChatGPT due to data leak risks,
GDPR compliance, or IP concerns - as error messages may contain sensitive data like queries, table
names, or PII.

Screenshot or video (only for visual changes)

showExceptionLinks = true (default) showExceptionLinks = false
Links visible on localhost Links hidden
image

GitHub Issue Link (if applicable)

Closes #11238

Testing Plan

  • Unit Tests: Added test case in ExceptionElement.test.tsx to verify links are hidden when
    showExceptionLinks is false
  • Added config option to config_test.py options list
  • Manual testing: Verified links appear when true (default) and hide when false

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@karubian karubian requested a review from a team as a code owner December 26, 2025 22:46
@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Dec 26, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for contributing to Streamlit! 🎈

Please make sure you have read our Contributing Guide. You can find additional information about Streamlit development in the wiki.

The review process:

  1. Initial triage: A maintainer will apply labels, approve CI to run, and trigger AI-assisted reviews. Your PR may be flagged with status:needs-product-approval if the feature requires product team sign-off.

  2. Code review: A core maintainer will start reviewing your PR once:

    • It is marked as 'ready for review', not 'draft'
    • It has status:product-approved (or doesn't need it)
    • All CI checks pass
    • All AI review comments are addressed

We're receiving many contributions and have limited review bandwidth — please expect some delay. We appreciate your patience! 🙏

@lukasmasuch lukasmasuch added change:feature PR contains new feature or enhancement implementation impact:users PR changes affect end users status:needs-product-approval PR requires product approval before merging labels Dec 27, 2025
@lukasmasuch lukasmasuch requested a review from Copilot December 27, 2025 08:55
@lukasmasuch
Copy link
Copy Markdown
Collaborator

@cursor review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new client.showExceptionLinks configuration option that allows users to disable external help links (Copy, Ask Google, Ask ChatGPT) displayed in exception messages when running on localhost. This addresses privacy and security concerns for organizations that prohibit ChatGPT usage due to data leak risks, GDPR compliance, or intellectual property concerns.

Key Changes:

  • Added client.showExceptionLinks config option (default: true) in Python backend
  • Extended protobuf Config message with show_exception_links field
  • Updated frontend to conditionally render exception links based on the config value

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
proto/streamlit/proto/NewSession.proto Added show_exception_links field to Config message (field number 9)
lib/streamlit/config.py Defined new client.showExceptionLinks config option with description and default value
lib/streamlit/runtime/app_session.py Populated the protobuf config message with the new option value
lib/tests/streamlit/config_test.py Added config option key to test assertions
frontend/lib/src/components/core/LibConfigContext.tsx Added showExceptionLinks property to context interface with documentation
frontend/app/src/components/StreamlitContextProvider.tsx Added property to provider props and memoization dependencies
frontend/app/src/App.tsx Added state variable for the config, populated from backend config, and passed to context provider
frontend/lib/src/components/elements/ExceptionElement/ExceptionElement.tsx Consumed context value and added conditional rendering of exception links
frontend/lib/src/test_util.tsx Added default value for test context
frontend/lib/src/components/elements/ExceptionElement/ExceptionElement.test.tsx Added test case verifying links are hidden when config is false

@karubian
Copy link
Copy Markdown
Contributor Author

Addressed the comment

@karubian
Copy link
Copy Markdown
Contributor Author

Thank you, looks like it needs security label as well. I can not edit it.

@jrieke
Copy link
Copy Markdown
Collaborator

jrieke commented Dec 30, 2025

Hey, thanks for the contribution. I'm in principle OK with adding this but:

  1. We should call it showErrorLinks to be consistent with the existing showErrorDetails config option.
  2. Can we turn the values into "auto" (same behavior as today, shows it on localhost, hides it otherwise), true (shows it always), and false (shows it never)? I think that would be a bit nicer, wdyt?

@karubian
Copy link
Copy Markdown
Contributor Author

Sounds good, I made the both changes.

@jrieke jrieke added status:product-approved Community PR is approved by product team and removed status:needs-product-approval PR requires product approval before merging labels Dec 31, 2025
@lukasmasuch lukasmasuch added ai-review If applied to PR or issue will run AI review workflow and removed ai-review If applied to PR or issue will run AI review workflow labels Dec 31, 2025
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR adds a new client.showErrorLinks configuration option that allows users to control whether external help links (Copy, Ask Google, Ask ChatGPT) are displayed in exception messages. The feature addresses privacy and security concerns for organizations that prohibit ChatGPT due to data leak risks, GDPR compliance, or IP concerns.

The implementation spans:

  • Backend: New config option in config.py, protobuf enum in NewSession.proto, and config population in app_session.py
  • Frontend: Context propagation through LibConfigContext, usage in ExceptionElement component
  • Tests: Frontend unit tests and protobuf compatibility tests

Code Quality

Strengths

  1. Follows existing patterns: The implementation closely follows the existing toolbarMode pattern for config handling.

  2. Clean context propagation: The showErrorLinks value flows correctly from App.tsxStreamlitContextProviderLibConfigContextExceptionElement.

  3. Type-safe enum usage: Uses protobuf enums (Config.ShowErrorLinks) consistently across frontend and backend.

  4. Proper memoization: The useMemo in StreamlitContextProvider.tsx correctly includes showErrorLinks in dependencies.

Issues

  1. PR Description Naming Mismatch (Minor): The PR title and description refer to client.showExceptionLinks, but the actual code uses client.showErrorLinks. The code is internally consistent; only the PR description needs updating.

  2. Inaccurate JSDoc comment (LibConfigContext.tsx, line 73-74):

  /**
   * Whether to show external help links (Google, ChatGPT) in exception displays
   * when running on localhost. Defaults to true.
   *
   * Consumed by:
   * @see ExceptionElement
   */

The comment says "Defaults to true" but the actual default is SHOW_ERROR_LINKS_AUTO (shows on localhost only). This is misleading.

  1. Hardcoded vs dynamic error message (app_session.py, line 1004):
    if enum_value is None:
        allowed_values = "auto, true, false"
        raise ValueError(
            f"Config {config_key!r} expects to have one of "
            f"the following values: {allowed_values}. "
            f"Current value: {config_value}"
        )

Unlike _get_toolbar_mode which dynamically generates allowed values from the enum, _get_show_error_links uses a hardcoded string. If enum values change, this could become out of sync. Consider using:

allowed_values = ", ".join(k.replace("SHOW_ERROR_LINKS_", "").lower() for k in Config.ShowErrorLinks.keys())

Test Coverage

Frontend Tests ✅

The frontend unit tests (ExceptionElement.test.tsx) are well-structured:

  • Tests that links are hidden when showErrorLinks is SHOW_ERROR_LINKS_FALSE on localhost
  • Tests that links are shown when showErrorLinks is SHOW_ERROR_LINKS_TRUE on non-localhost
  • Uses renderWithContexts helper correctly for context-dependent testing

Python Tests ✅

  • config_test.py: New option added to the config options list
  • proto_compatibility_test.py: New field added to Config message schema

Missing Tests (Acceptable)

  • No dedicated Python unit test for _get_show_error_links() function - but this follows the existing pattern where _get_toolbar_mode() also lacks dedicated tests
  • No E2E tests - acceptable given that unit tests cover the behavior and E2E tests are expensive

Backwards Compatibility

Protobuf Changes ✅

The protobuf changes are backwards compatible:

  • New optional field show_error_links (field number 9) added to Config message
  • New enum ShowErrorLinks with values starting at 0 (AUTO is the default)
  • No existing fields modified or removed

Config Default ✅

  • Default value is "auto" which preserves existing behavior (links shown on localhost only)
  • Users who don't configure this option will see no change

Security & Risk

Security Improvements ✅

This PR improves security by:

  • Allowing organizations to disable external links that could expose sensitive error data
  • Addressing concerns about ChatGPT data handling and GDPR compliance

Risk Assessment ✅

Low risk:

  • Feature is opt-in (requires explicit configuration to change behavior)
  • Default behavior unchanged
  • No breaking changes to existing APIs

Recommendations

  1. Update PR description to use the correct config name client.showErrorLinks (instead of client.showExceptionLinks)

  2. Fix JSDoc comment in LibConfigContext.tsx line 73:

    // Change "Defaults to true." to "Defaults to AUTO (shows on localhost only)."
  3. Consider dynamic error message (optional improvement): Change the hardcoded allowed values in _get_show_error_links() to dynamically generated values for maintainability.

Verdict

APPROVED: This is a well-implemented feature that addresses legitimate privacy/security concerns. The code follows existing patterns, is properly tested, and maintains backwards compatibility. The minor issues identified (PR description naming, JSDoc comment accuracy, hardcoded error message) are non-blocking and can be addressed in a follow-up if desired.


This is an automated AI review. Please verify the feedback and use your judgment.

@karubian karubian changed the title Add "client.showExceptionLinks` config option (#11238)" Add "client.showErrorLinks` config option (#11238)" Jan 4, 2026
@sfc-gh-lwilby sfc-gh-lwilby self-assigned this Jan 6, 2026
@sfc-gh-lwilby sfc-gh-lwilby added the ready-for-maintainer-review This PR is ready for maintainer attention to conduct final review before merge! label Jan 9, 2026
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe update the title of the test to specify "when no showErrorLinks config is set".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

And update this one to specify "should not render exception links for non-localhost when no showErrorLinks config is set" (it looks like this test also has an error and should be non-localhost not localhost).

expect(screen.getByText("Ask Google")).toBeInTheDocument()
expect(screen.getByText("Ask ChatGPT")).toBeInTheDocument()
})
})
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think these tests are fairly cheap to run, so we might as well add the other cases (i.e. config true + localhost, config false + non-localhost). Maybe you could parameterize them to reduce the reading overhead.


// See config option "client.showErrorLinks".
enum ShowErrorLinks {
SHOW_ERROR_LINKS_AUTO = 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We don't do this for all enums, but the proto best practices specify using this first value as an unspecified value. So, SHOW_ERROR_LINKS_UNSPECIFIED = 0; and then SHOW_ERROR_LINKS_AUTO = 1;.

return enum_value


def _get_show_error_links() -> Config.ShowErrorLinks.ValueType:
Copy link
Copy Markdown
Collaborator

@sfc-gh-lwilby sfc-gh-lwilby Jan 12, 2026

Choose a reason for hiding this comment

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

[suggestion: non-blocking] I guess we can keep this code like this, I see this follows the _get_toolbar_mode pattern above. It seems like the intention is to not have to keep a list of valid config options in sync with the proto enum. I am not sure how often we would be adding enum values to make this a big concern though. It would be easier to read if we just had something like this ...

allowed_values = ["auto", "true", "false"]
config_value = config.get_option("client.showErrorLinks")
if config_value not in allowed_values:
   ... error

map_to_enum = {
"auto" : Config.ShowErrorLinks.SHOW_ERROR_LINKS_AUTO,
...
}

return map_to_enum.get(config_value)

Not blocking, since we are doing this above.

if enum_value is None:
allowed_values = ", ".join(
k.replace("SHOW_ERROR_LINKS_", "").lower()
for k in Config.ShowErrorLinks.keys() # noqa: SIM118
Copy link
Copy Markdown
Collaborator

@sfc-gh-lwilby sfc-gh-lwilby Jan 12, 2026

Choose a reason for hiding this comment

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

If you don't do the above changes, we should change this to an array comprehension so we don't need this noqa.

I.e.

allowed_values = [k.replace("SHOW_ERROR_LINKS_").lower() for k in Config.ShowErrorLinks.keys()]

return enum_value


def _get_show_error_links() -> Config.ShowErrorLinks.ValueType:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it would be good to add some tests for this function, I think it won't be covered currently. Cursor is recommending adding the tests into app_session_test.py and you can use with patch_config_options({"client.toolbarMode": config_value}): to test the different options map to the right enum values and also that invalid values throw the right error and no config maps to the default.

@karubian
Copy link
Copy Markdown
Contributor Author

Thanks for the comments @sfc-gh-lwilby, addressed and resolved the conflict with the last 2 commits.

@sfc-gh-lwilby
Copy link
Copy Markdown
Collaborator

Thanks @karubian ! I will try to take a look tomorrow. I have re-run your CI.

@karubian
Copy link
Copy Markdown
Contributor Author

karubian commented Jan 21, 2026

Thank you, remaining CI issue does not look related to the change.

@karubian
Copy link
Copy Markdown
Contributor Author

Could you look into the permission issue in CI? Please LMK if it is related to the change.

@sfc-gh-lwilby
Copy link
Copy Markdown
Collaborator

Could you look into the permission issue in CI? Please LMK if it is related to the change.

@karubian I think Lukas merged something on Friday that should fix this permission error -- here e356d2c

Copy link
Copy Markdown
Collaborator

@sfc-gh-lwilby sfc-gh-lwilby left a comment

Choose a reason for hiding this comment

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

@karubian thanks for addressing all my feedback. Looks ready to merge 🚀

@sfc-gh-lwilby sfc-gh-lwilby merged commit da62861 into streamlit:develop Jan 28, 2026
39 checks passed
@jrieke
Copy link
Copy Markdown
Collaborator

jrieke commented Jan 29, 2026

Awesome, thanks for getting this merged! @karubian we'd love to send you some swag as a little thank you, feel free to fill out this form: https://docs.google.com/forms/d/e/1FAIpQLSe7cXh3H1DmrgNpVew9qViGIHX7vdEbTv5isA44_z5bgaKTKg/viewform

@karubian
Copy link
Copy Markdown
Contributor Author

karubian commented Feb 2, 2026

Thank you for your help and reviews. I filled the form.

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

Labels

change:feature PR contains new feature or enhancement implementation impact:users PR changes affect end users ready-for-maintainer-review This PR is ready for maintainer attention to conduct final review before merge! status:product-approved Community PR is approved by product team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to remove link to Google and ChatGPT for Exception, even when using Localhost (#11021)

5 participants