Skip to content

st.Page accepts slash-only url_path (e.g. "///") without raising an exception #13952

@t0k0shi

Description

@t0k0shi

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

st.Page(my_func, title="Test", url_path="///") does not raise an exception for internal pages. The empty string check at line 316 uses strip() (whitespace
only), so "///" passes. Then strip("/") at line 321 reduces it to "", resulting in a silently empty url_path that could cause routing issues.

Reproducible Code Example

import streamlit as st

  def my_page():
      st.write("Hello")

  def home():
      st.write("Home")

  # Expected: raises StreamlitAPIException
  # Actual: no error, page.url_path becomes ""
  pages = [
      st.Page(home, title="Home", default=True),
      st.Page(my_page, title="Test", url_path="///"),
  ]
  pg = st.navigation(pages)
  pg.run()

Steps To Reproduce

  1. Create a st.Page with url_path="///"
  2. Run the app
  3. No exception is raised
  4. The page's url_path is an empty string

Expected Behavior

st.Page should raise a StreamlitAPIException when url_path resolves to an empty string after stripping slashes, consistent with the behavior for url_path="".

Current Behavior

No exception is raised. url_path silently becomes an empty string.

In lib/streamlit/navigation/page.py (lines 316-321):

  if url_path.strip() == "" and not default:    # "///" is not whitespace-empty, passes
      raise StreamlitAPIException(...)
  self._url_path = url_path.strip("/")          # becomes "" — no further check

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • Streamlit version: develop branch (HEAD)
  • Python version: 3.10
  • Operating System: Ubuntu
  • Browser: N/A (code-level issue)

Additional Information

Found while reviewing #13691. The external URL code path added in that PR already handles this correctly by applying strip("/") before the empty check (lines
260-261).

A possible fix:

  self._url_path = url_path.strip("/")
  if self._url_path == "" and not default:
      raise StreamlitAPIException(
          "The URL path cannot be an empty string unless the page is the default page."
      )

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions