Skip to content

TraitError: The 'synctex_command' trait expected a boolean, not the str 'synctex' (Python 3.13) #255

@X0bang

Description

@X0bang

Description

When attempting to use the SyncTeX feature (reverse search from PDF to source code, or forward search from code to PDF), the server returns a 500 Internal Server Error.

The backend logs reveal a TypeError caused by attempting to use a Boolean value (c.synctex_command) as a string in command construction.

Steps to Reproduce

  1. Install jupyterlab-latex==4.3.0 in a Python 3.13 environment with JupyterLab 4.5.0
  2. Open a valid .tex file in JupyterLab
  3. Build the LaTeX file to generate the .pdf and .synctex.gz files
  4. Right-click on the PDF preview and select "Scroll Editor to Page" (or Ctrl/Cmd + Click on the PDF)
  5. Observe a "500 Internal Server Error" in the browser console

Expected Behavior

The editor should navigate to the corresponding line in the .tex file without errors.

Environment

  • Operating System: Ubuntu 22.04 LTS
  • Python Version: 3.13.9
  • JupyterLab Version: 4.5.0
  • jupyterlab-latex Version: 4.3.0
  • Browser: Chrome 143

Error Logs

Primary Error

TypeError: sequence item 0: expected str instance, bool found
    at jupyterlab_latex/synctex.py:148, in run_synctex
    self.log.debug(f'jupyterlab-latex: run: {" ".join(cmd)} (CWD: {os.getcwd()})')
Full Traceback ```python [E 2025-12-12 01:35:28.536 SingleUserLabApp web:1934] Uncaught exception GET /user/username/latex/synctex/... Traceback (most recent call last): File ".../tornado/web.py", line 1848, in _execute result = await result File ".../tornado/gen.py", line 796, in run yielded = self.gen.throw(exc) File ".../jupyterlab_latex/synctex.py", line 197, in get out = yield self.run_synctex(cmd) File ".../tornado/gen.py", line 783, in run value = future.result() File ".../tornado/gen.py", line 239, in wrapper yielded = ctx_run(next, result) File ".../jupyterlab_latex/synctex.py", line 148, in run_synctex self.log.debug(f'jupyterlab-latex: run: {" ".join(cmd)} (CWD: {os.getcwd()})') TypeError: sequence item 0: expected str instance, bool found ```

Root Cause

The issue is in two methods in synctex.py:

  1. build_synctex_edit_cmd (around line 85)
  2. build_synctex_view_cmd (around line 100)

Both methods incorrectly use c.synctex_command (a Boolean trait) directly in the command tuple where a string is expected:

cmd = (
    c.synctex_command,  # ❌ This is a Boolean, not a string!
    'edit',  # or 'view'
    ...
)

When the code later tries to join this tuple as strings (line 148), it fails because the first element is False instead of 'synctex'.

Proposed Fix

Fix 1: In build_synctex_edit_cmd (around line 83-88)

Before:

cmd = (
    c.synctex_command,
    'edit',
    '-o',
    f'{pos["page"]}:{pos["x"]}:{pos["y"]}:{pdf_path}'
)

After:

cmd = (
    'synctex',  # ✅ Hardcode the command string
    'edit',
    '-o',
    f'{pos["page"]}:{pos["x"]}:{pos["y"]}:{pdf_path}'
)

Fix 2: In build_synctex_view_cmd (around line 98-104)

Before:

cmd = (
    c.synctex_command,
    'view',
    '-i',
    f'{pos["line"]}:{pos["column"]}:{tex_path}',
    '-o',
    f'{pdf_path}'
)

After:

cmd = (
    'synctex',  # ✅ Hardcode the command string
    'view',
    '-i',
    f'{pos["line"]}:{pos["column"]}:{tex_path}',
    '-o',
    f'{pdf_path}'
)

Alternative Solution

If c.synctex_command is intended to allow custom command paths, it should be changed to:

cmd = (
    str(c.synctex_command) if isinstance(c.synctex_command, str) else 'synctex',
    # ... rest of the command
)

If this approach looks reasonable, I'm happy to open a Pull Request with the fix.

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