Bug: display_file tool produces doubled/invalid file paths in UI
Summary
The display_file tool always returns full_path as an absolute path (e.g. C:\Users\....\Documents\GIT\scratchpad\file.md). The cptr UI then concatenates workspace + full_path, producing a doubled, invalid path like:
C:\Users\...\Documents\GIT/C:\Users\...\Documents\GIT\scratchpad\file.md
This makes file links from display_file unclickable/broken in the UI.
Environment
- cptr version: 0.9.21
- OS: Windows 11
- Architecture: AMD64
- Workspace path:
C:\Users\...\Documents\GIT
Reproduction
Call display_file with any relative path, e.g.:
display_file(path="scratchpad/test.md")
Tool response (JSON):
{
"type": "file",
"path": "scratchpad\\test.md",
"full_path": "C:\\Users\\....\\Documents\\GIT\\scratchpad\\test.md",
"workspace": "C:\\Users\\.....\\Documents\\GIT",
"name": "test.md",
"size": 7467,
"mime_type": "text/markdown",
"kind": "markdown"
}
UI rendering (broken):
The UI displays a link/path constructed as {workspace}/{full_path}:
C:\Users\....\Documents\GIT/C:\Users\....\Documents\GIT\scratchpad\test.md
This path is invalid — it duplicates the workspace root prefix.
Tested Variants
All of these produce the same doubled-path result in the UI:
Input path |
Tool full_path output |
UI renders |
scratchpad/test.md |
C:\Users\...\GIT\scratchpad\test.md |
C:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.md |
./scratchpad/test.md |
C:\Users\...\GIT\scratchpad\test.md |
C:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.md |
test.md (root) |
C:\Users\...\GIT\test.md |
C:\Users\...\GIT/C:\Users\...\GIT\test.md |
C:\Users\...\test.md |
C:\Users\...\GIT\scratchpad\test.md |
C:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.md |
/scratchpad/test.md |
(rejected: "Path traversal rejected") |
N/A |
/test.md |
(rejected: "Path traversal rejected") |
N/A |
Root Cause
The display_file tool resolves the input path to an absolute path and stores it in full_path. The UI then constructs the display path as {workspace}/{full_path}. Since full_path already starts with the workspace path, the workspace prefix is duplicated.
Expected Behavior
The UI should use either:
full_path directly (it's already absolute), or
{workspace}/{path} (joining workspace with the relative path)
...but not {workspace}/{full_path}.
Bug:
display_filetool produces doubled/invalid file paths in UISummary
The
display_filetool always returnsfull_pathas an absolute path (e.g.C:\Users\....\Documents\GIT\scratchpad\file.md). The cptr UI then concatenatesworkspace+full_path, producing a doubled, invalid path like:This makes file links from
display_fileunclickable/broken in the UI.Environment
C:\Users\...\Documents\GITReproduction
Call
display_filewith any relative path, e.g.:Tool response (JSON):
{ "type": "file", "path": "scratchpad\\test.md", "full_path": "C:\\Users\\....\\Documents\\GIT\\scratchpad\\test.md", "workspace": "C:\\Users\\.....\\Documents\\GIT", "name": "test.md", "size": 7467, "mime_type": "text/markdown", "kind": "markdown" }UI rendering (broken):
The UI displays a link/path constructed as
{workspace}/{full_path}:This path is invalid — it duplicates the workspace root prefix.
Tested Variants
All of these produce the same doubled-path result in the UI:
pathfull_pathoutputscratchpad/test.mdC:\Users\...\GIT\scratchpad\test.mdC:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.md./scratchpad/test.mdC:\Users\...\GIT\scratchpad\test.mdC:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.mdtest.md(root)C:\Users\...\GIT\test.mdC:\Users\...\GIT/C:\Users\...\GIT\test.mdC:\Users\...\test.mdC:\Users\...\GIT\scratchpad\test.mdC:\Users\...\GIT/C:\Users\...\GIT\scratchpad\test.md/scratchpad/test.md/test.mdRoot Cause
The
display_filetool resolves the inputpathto an absolute path and stores it infull_path. The UI then constructs the display path as{workspace}/{full_path}. Sincefull_pathalready starts with the workspace path, the workspace prefix is duplicated.Expected Behavior
The UI should use either:
full_pathdirectly (it's already absolute), or{workspace}/{path}(joining workspace with the relative path)...but not
{workspace}/{full_path}.