Skip to content

tldr calls: JavaScript call graph always returns empty (missing language handler) #149

@tnakamura2026

Description

@tnakamura2026

Summary

tldr calls returns an empty call graph for JavaScript projects, and crashes when a file path (instead of directory) is passed.

Environment

  • tldr version: 1.5.2
  • Project type: Node.js/Express backend (.js, .cjs, .mjs files)

Bug 1: JavaScript call graph not implemented (silent empty result)

Steps to reproduce

tldr calls /path/to/js-project --lang javascript
# Returns: {"edges": [], "count": 0}

Even without --lang, auto detection on a JS project returns javascript as the first language, so the same empty result occurs.

Root cause

In cross_file_calls.py, build_project_call_graph() has branches for python, typescript, go, rust, java, c, phpbut no branch for javascript:

# cross_file_calls.py ~L3300
if language == "python":
    _build_python_call_graph(...)
elif language == "typescript":
    _build_typescript_call_graph(...)
elif language == "go":
    ...
# ← javascript is missing!

Meanwhile, scan_project() already supports javascript correctly (.js, .jsx, .mjs, .cjs). Only the call graph builder is missing.

Expected behavior

tldr calls should work for JavaScript projects, similar to TypeScript.

Suggested fix

Add a _build_javascript_call_graph() function (or reuse _build_typescript_call_graph with a language parameter), and add the missing branch:

elif language == "javascript":
    _build_javascript_call_graph(root, graph, func_index, workspace_config)

Bug 2: Crash when file path passed instead of directory

Steps to reproduce

tldr calls /path/to/backend/index.js
# Error: [Errno 20] Not a directory: '/path/to/backend/index.js/.tldr/cache'

Root cause

In cli.py, _get_or_build_graph() does not validate that the path is a directory:

# cli.py ~L476
project = Path(project_path).resolve()
cache_dir = project / ".tldr" / "cache"   # tries to treat file as dir
cache_dir.mkdir(parents=True, exist_ok=True)  # → [Errno 20] Not a directory

Suggested fix

Add directory validation at the start of the calls command handler:

elif args.command == "calls":
    if not Path(args.path).is_dir():
        print(f"Error: '{args.path}' is not a directory", file=sys.stderr)
        sys.exit(1)
    ...

Workaround

Until fixed, use structure + imports as alternatives:

tldr structure /path/to/backend --lang javascript
tldr imports /path/to/backend/index.js

Or use --lang typescript if the project has .ts files.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions