`_next_filename()` can cause unintended OSError for "File name too long" on Fedora/Red Hat

Aperta
#409 2 commenti 1 reazione 1 assegnatario Vedi su GitHub

@ayjayt ci sta già lavorando.

Dal 26/9/2025.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug P2

Description of the issue

Quickest summary:

  • the kaleido._fig_tools._next_filename function checks if a file at path / f"{prefix}.{ext}" exists (line 148)
  • The value of prefix can originate from the _build_full_path function in the same module, where prefix is potentially taken from the title text of a Plotly Figure
  • If a Plotly figure has a long title, this can lead to an OSError (dependent on the OS) because the long title text may exceed the OS's max allowable filename length.
  • In my brief testing, I can reproduce this error on Fedora/Red Hat, but not on Windows 11 (I haven't yet tested macOS).

Note I ran into this error while using Plotly, but traced the source of the error to within the Kaleido package. That's what led me to submit the error here.

One other note: I encountered this error while trying to use fig.to_image(), intending to go directly from a Plotly Figure to in-memory bytes, and saving the bytes to the filesystem elsewhere. In that sense: the check for "does a file with this name exist" in _next_filename is not necessary. That may be an opportunity to decouple the fig.to_image() function from needing to check for existing files.

Potential Fixes

  • Slicing first N characters of prefix in _build_full_path to a value of N<=100?
# kaleido/_fig_tools.py
def _build_full_path(...):
    ...
    prefix = prefix[:100] or "fig"  # line 191
    ...
  • Decouple fig.to_image() from using _next_filename() as it would not need to check filenames to output in-memory bytes (I think, could be wrong).

I'd be happy to (try to) submit a PR if that would be helpful.

Code to Reproduce

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go


# EXAMPLE WITH REASONABLE TITLE
title_text: str = "A title of typical length"

# make a basic figure
df: pd.DataFrame = px.data.gapminder().query("country=='Canada'")
fig: go.Figure = px.line(df, x="year", y="lifeExp", title=title_text)

fig_img_bytes = fig.to_image()
print("Short title bytes:", len(fig_img_bytes))


# EXAMPLE WITH VERY LONG TITLE
title_text: str = f"An exceptionally long title: {'a' * 500}"

# make a basic figure
df: pd.DataFrame = px.data.gapminder().query("country=='Canada'")
fig: go.Figure = px.line(df, x="year", y="lifeExp", title=title_text)

fig_img_bytes = fig.to_image()  # <-- causes OSError on Fedora/Red Hat
print("Long title bytes:", len(fig_img_bytes))

Environment to Reproduce

OS:

  • Fedora Linux 42 (also tested+observed on Red Hat)
  • NOT reproducible on Windows 11 (even with a 1 million-character-long filename)

Python:

  • 3.13.7 (also tested+observed on 3.12.7)

Output of pip freeze:

asttokens==3.0.0
attrs==25.3.0
choreographer==1.1.1
comm==0.2.3
debugpy==1.8.17
decorator==5.2.1
executing==2.2.1
fastjsonschema==2.21.2
iniconfig==2.1.0
ipykernel==6.30.1
ipython==9.5.0
ipython-pygments-lexers==1.1.1
jedi==0.19.2
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
jupyter-client==8.6.3
jupyter-core==5.8.1
kaleido==1.1.0
logistro==1.1.0
matplotlib-inline==0.1.7
narwhals==2.5.0
nbformat==5.10.4
nest-asyncio==1.6.0
numpy==2.3.3
orjson==3.11.3
packaging==25.0
pandas==2.3.2
parso==0.8.5
pexpect==4.9.0
platformdirs==4.4.0
plotly==6.3.0
pluggy==1.6.0
prompt-toolkit==3.0.52
psutil==7.1.0
ptyprocess==0.7.0
pure-eval==0.2.3
pygments==2.19.2
pytest==8.4.2
pytest-timeout==2.4.0
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==27.1.0
referencing==0.36.2
rpds-py==0.27.1
simplejson==3.20.1
six==1.17.0
stack-data==0.6.3
tornado==6.5.2
traitlets==5.14.3
tzdata==2025.2
wcwidth==0.2.14

Thank you!

Lingua principale
Python
Stelle
504
Fork
65
Merge medio
6g 9h
PR unite (30g)
2

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di plotly/kaleido

Tutte le issue di plotly/kaleido

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.