streamlit: StreamlitAPIException: Could not find page: 'pages/name.py'. Must be the file path relative to the main script, from the directory: ..

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

Hello!

Key points

I think I found one bug when try to do st.sidebar.page_link.

What was the error

I have the following project structure:

my_project
├── .streamlit
│   └── config.toml
├── pages
│   └── bia.py
└── main.py

After doing:

import streamlit as st

st.sidebar.page_link(page="pages/bia.py", label="IA")

I get: error-streamlit

What I found

I was looking into the source code and I found that over this piece of code in streamlit.elements.widgets.button:

667        main_script_path = os.path.join(os.getcwd(), ctx_main_script)
668        main_script_directory = os.path.dirname(main_script_path)
669
670        # Convenience for handling ./ notation and ensure leading / doesn't refer to root directory
671        page = os.path.normpath(page.strip("/"))
672
673        # Build full path
674        requested_page = os.path.join(main_script_directory, page)

Something is not working as expected. The value of main_script_path came with a . at the end of the path that change the behaviour of the if statement on line 681, so never a full_path inside the pages folder (c:\users\estebansanchez\my_project\pages\bia.py) will match with the page I want to link (c:\users\estebansanchez\my_project\.\pages\bia.py).

678        for page_data in all_app_pages:
679            full_path = page_data["script_path"]
680            page_name = page_data["page_name"].replace("_", " ")
681            if requested_page == full_path:

Hope it help, thanks and congrats for such wonderfull tool, I was playing with it and it is “la ostia” as we said in Spain, which that is so so cool.

Reproducible Code Example

import streamlit as st

st.sidebar.page_link(page="pages/bia.py", label="IA")

Steps To Reproduce

  1. Go to my_project.
  2. Execute through terminal streamlit run main.py
  3. The error appears on Chrome.

Expected Behavior

I would expect a redirection to a page, just as it said in the tutorial of Create custom navigation menus here.

Current Behavior

StreamlitAPIException: Could not find page: 'pages/bia.py'. Must be the file path relative to the main script, from the directory: ..

Is this a regression?

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

Debug info

  • Streamlit version: 1.31.0
  • Python version: 3.9.13
  • Operating System: Microsoft Windows 11 Version 23H2
  • Browser: Chrome

Additional Information

No response

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Reactions: 17
  • Comments: 16 (1 by maintainers)

Most upvoted comments

If this issue affects you, please react with a 👍 (thumbs up emoji) to the initial post.

Your feedback helps us prioritize which bugs to investigate and address first.

Visits

Eureka!

After some manual testing with different Windows environments looks like I found a root cause.

When using autocompletion in the terminal (I used Pycharm terminal in Windows, probably the same for any other setup), when you press tab after streamlit run m it suggests streamlit run .\main.py , and usually streamlit app works as expected.

But in this case we ended up to have main Script Path "C:\Users\AAA\Desktop\myproject\.\main.py" and Main Script directory "C:\Users\AAA\Desktop\myproject\." which then leads to this exception in st.page_link and in st.switch_page primitives.

So the temporarily workaround before fixing this issue, should be just run streamlit app without leading .\ prefix. Like streamlit run main.py instead of streamlit run .\main.py

Hello:

I have been making tests, here is the insight I have found:

Config 1, when logging in: On windows: streamlit run client.py --server.maxMessageSize 1000 --server.runOnSave=True st.switch_page(“pages/client_presentacion.py”) Sidebar links: file_presentacion = os.path.join(os.getcwd(), “pages”, “client_presentacion.py”) st.page_link(file_presentacion, label=“Presentación”, icon=“⚓”) It works! On linux container: ENTRYPOINT [“streamlit”, “run”, “client.py”, “–server.port=8501”, “–server.address=0.0.0.0”, “–server.maxMessageSize=1000”] StreamlitAPIException: Could not find page: ‘app/pages/client_presentacion.py’. Must be the file path relative to the main script, from the directory: app.

Traceback: File “/app/pages/client_presentacion.py”, line 11, in <module> create_sidebar() File “/app/client_menu.py”, line 36, in create_sidebar st.page_link(file_presentacion, label=“Presentación”, icon=“⚓”) So its not failing on the swtich page but the sidebar links

Config 2, when logging in: On windows: streamlit run client.py --server.maxMessageSize 1000 --server.runOnSave=True file_presentacion = os.path.join(os.getcwd(), “pages”, “client_presentacion.py”) st.switch_page(file_presentacion ) Sidebar links: file_presentacion = os.path.join(os.getcwd(), “pages”, “client_presentacion.py”) st.page_link(file_presentacion, label=“Presentación”, icon=“⚓”) It works again! On linux container: ENTRYPOINT [“streamlit”, “run”, “client.py”, “–server.port=8501”, “–server.address=0.0.0.0”, “–server.maxMessageSize=1000”] StreamlitAPIException: Could not find page: ‘app/pages/client_presentacion.py’. Must be the file path relative to the main script, from the directory: app.

Traceback: File “/app/client.py”, line 64, in <module> main() File “/app/client.py”, line 50, in main st.switch_page(file_presentacion) So its failing with the absolute path this time even though on windows works

Config 3, when logging in: On windows: streamlit run client.py --server.maxMessageSize 1000 --server.runOnSave=True st.switch_page(“pages/client_presentacion.py”) Sidebar links: st.page_link(“pages/client_presentacion.py”, label=“Presentación”, icon=“⚓”) It works again! On linux container: ENTRYPOINT [“streamlit”, “run”, “client.py”, “–server.port=8501”, “–server.address=0.0.0.0”, “–server.maxMessageSize=1000”] Now it works Aditional info: On windows, configs 1, 2,3 are not working when i move the project folder to a network location, they are only working on my desktop

So, to sum up: Windows–> It does work on my desktop but it doesnt on a shared folder, I didnt try the .\ because it finally worked on my container in config 3 Linux–> you can´t use absolute paths, use “/pages/my_file.py” and it works

Hello! I am @lovin-bear I deployed the app today in a python:3.11.7 container and the bug reapeared: Output when I run the code you provided in my windows 10 in the desktop folder as workdir (no bug): Main Script File

“client.py” Current Working Directory

“C:\Users\dfervenza\Desktop\streamlit_app” Normalized Current Working Directory

“C:\Users\dfervenza\Desktop\streamlit_app” Main Script Path

“C:\Users\dfervenza\Desktop\streamlit_app\client.py” Main Script Directory

“C:\Users\dfervenza\Desktop\streamlit_app” Normalized Path

“pages\client_presentacion.py” Requested Page

“C:\Users\dfervenza\Desktop\streamlit_app\pages\client_presentacion.py” All Pages Page

[ 0:{ “page_script_hash”:“2d5864fe4ab14d4494a119b54f63c3cf” “page_name”:“client” “icon”:“” “script_path”:“C:\Users\dfervenza\Desktop\streamlit_app\client.py” } 1:{ “page_script_hash”:“cc142648052dadf78337447bd7191077” “page_name”:“client_conclusiones” “icon”:“” “script_path”:“C:\Users\dfervenza\Desktop\streamlit_app\pages\client_conclusiones.py” } 2:{ “page_script_hash”:“4f96621512cbd9acde2076e5831b129a” “page_name”:“client_global” “icon”:“” “script_path”:“C:\Users\dfervenza\Desktop\streamlit_app\pages\client_global.py” } 3:{ “page_script_hash”:“b51c5769842dec072a4d71b980d28026” “page_name”:“client_presentacion” “icon”:“” “script_path”:“C:\Users\dfervenza\Desktop\streamlit_app\pages\client_presentacion.py” } 4:{ “page_script_hash”:“dae6dbb8b23c4dd436896d82c43f1653” “page_name”:“client_top_50” “icon”:“” “script_path”:“C:\Users\dfervenza\Desktop\streamlit_app\pages\client_top_50.py” } ] [Page Two](file:///C:/Users/dfervenza/Desktop/streamlit_app/pages/client_presentacion.py)

here is the output in the python container: Main Script File

“client.py” Current Working Directory

“/app” Normalized Current Working Directory

“/app” Main Script Path

“/app/client.py” Main Script Directory

“/app” Normalized Path

“pages/client_presentacion.py” Requested Page

“/app/pages/client_presentacion.py” All Pages Page

[ 0:{ “page_script_hash”:“2d5864fe4ab14d4494a119b54f63c3cf” “page_name”:“client” “icon”:“” “script_path”:“/app/client.py” } 1:{ “page_script_hash”:“4c4eec49987892b5edc73cd0801ae620” “page_name”:“client_conclusiones” “icon”:“” “script_path”:“/app/pages/client_conclusiones.py” } 2:{ “page_script_hash”:“6aa48767d3d240e31992a9403ec7d9bf” “page_name”:“client_global” “icon”:“” “script_path”:“/app/pages/client_global.py” } 3:{ “page_script_hash”:“b08d81b3c82fc0653878f615dfef68b0” “page_name”:“client_presentacion” “icon”:“” “script_path”:“/app/pages/client_presentacion.py” } 4:{ “page_script_hash”:“6ee34f47fd89acf239ddd0ac73ea5532” “page_name”:“client_top_50” “icon”:“” “script_path”:“/app/pages/client_top_50.py” } ] Page Two

The thing is that I have a loggin page: if st.button(“Aceptar”, type=“primary”): if usuario == “paco” and password == “paco”: st.session_state[“logeado”] = True st.success(“Sesion iniciada”) time.sleep(0.50) st.switch_page(file_presentacion) The bug appears when logging in, if i click on page 2, it redirects to main page so the bug does not appear:

StreamlitAPIException: Could not find page: ‘app/pages/client_presentacion.py’. Must be the file path relative to the main script, from the directory: app.

Traceback: File “/app/client.py”, line 102, in <module> main() File “/app/client.py”, line 88, in main st.switch_page(file_presentacion)

Please tell me if you need more info

Hey @esan94 and @lovin-bear ! Thank you so much for your help.

Not having windows laptops makes debugging a little harder. I was hoping to reproduce this on a windows laptop, but after getting it set up, it worked as expected.

I think @esan94 is providing some interesting insight with this weird . in the path. I’m trying to figure out where it’s coming from. Is it possible to run the following Streamlit script and share the output? I would appreciate any output from people who are experiencing this error. My only thought is that os.getcwd() get current working directory is providing the extra ., which makes this really weird.

import os
import streamlit as st
from streamlit import source_util
from streamlit.runtime.scriptrunner import get_script_run_ctx


page = "pages/page_two.py" # MODIFY TO YOUR PAGE

ctx = get_script_run_ctx()
ctx_main_script = ""
if ctx:
  ctx_main_script = ctx.main_script_path

st.write("**Main Script File**")
st.text(f"\"{ctx_main_script}\"")

st.write("**Current Working Directory**")
st.text(f"\"{os.getcwd()}\"")

st.write("**Normalized Current Working Directory**")
st.text(f"\"{os.path.normpath(os.getcwd())}\"")

st.write("**Main Script Path**")
main_script_path = os.path.join(os.getcwd(), ctx_main_script)
st.text(f"\"{main_script_path}\"")

st.write("**Main Script Directory**")
main_script_directory = os.path.dirname(main_script_path)
st.text(f"\"{main_script_directory}\"")

st.write("**Normalized Path**")
page = os.path.normpath(page)
st.text(f"\"{page}\"")

st.write("**Requested Page**")
requested_page = os.path.join(main_script_directory, page)
st.text(f"\"{requested_page}\"")

st.write("**All Pages Page**")
all_app_pages = list(source_util.get_pages(ctx_main_script).values())
st.json(all_app_pages, expanded=True)

st.page_link(page, label="Page Two")

Welcome to screenshot, but I can determine where it’s coming from

Hey @esan94, thank you for opening this issue!

I was able to reproduce the problem on Windows, and I can confirm that this is a bug.