Skip to content

Conversation

@bastianseipp
Copy link

Summary

Fixes a critical bug in the markdown file download link handler that prevented files from being downloaded correctly through markdown links.

The issue occurred in MarkdownComponents.tsx where the file_id and filename were being extracted incorrectly from URLs in the format files/{userId}/{file_id}. The .pop() method was applied twice in reverse order, causing:

  • The userId to be assigned to the file_id variable
  • The actual file_id to be used as the filename

This resulted in download failures with 404 errors because the API endpoint was being called with /api/files/download/{userId}/{userId} instead of the correct /api/files/download/{userId}/{file_id}.

Root cause: When splitting the URL path and using .pop() twice, the values were extracted in reverse order (last element first, then second-to-last), inverting the userId and file_id.

Solution:

  • Changed to directly access parts[2] to get the correct file_id
  • Use the markdown link text (children) as the filename for better UX
  • Added children to the useMemo dependency array to properly track changes

This fix enables MCP tools and other integrations to serve files through LibreChat's download system using markdown links.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Translation update

Testing

Test Process

  1. Create a file in the uploads directory: /app/uploads/{userId}/{filename}
  2. Create a corresponding MongoDB file record with:
    • file_id: UUID v4
    • user: MongoDB ObjectId matching the user
    • filepath: /uploads/{userId}/{filename}
    • source: "local"
  3. Generate a markdown link in a chat message: [filename.ext](files/{userId}/{file_id})
  4. Click the link
  5. Verify the file downloads correctly

Test Configuration:

  • Browser: Chrome/Edge/Firefox
  • LibreChat instance with local file storage
  • MongoDB with file records
  • Test file created via MCP tool or manual insertion

Expected Behavior

Before fix:

  • Click link → API call to /api/files/download/{userId}/{userId} → 404 error

After fix:

  • Click link → API call to /api/files/download/{userId}/{file_id} → File downloads successfully

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • I have made pertinent documentation changes
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes
  • Any changes dependent on mine have been merged and published in downstream modules
  • A pull request for updating the documentation has been submitted

Bastian Seipp and others added 2 commits November 14, 2025 13:37
The markdown link handler was incorrectly extracting file_id and filename
from URLs in the format files/{userId}/{file_id}. The .pop() method was
applied twice in reverse order, causing the userId to be assigned to the
file_id variable and the actual file_id to be used as filename.

This caused downloads to fail with 404 errors as the API was called with
/api/files/download/{userId}/{userId} instead of the correct
/api/files/download/{userId}/{file_id}.

Fixed by directly accessing parts[2] to get the file_id and using the
link text (children) as the filename. Also added children to the useMemo
dependency array to properly track changes.
Introduced a new test suite for the Markdown link component to verify the correct extraction of file_id from markdown file links. The tests cover various scenarios, including standard file paths, alternative output paths, and edge cases with UUID-style file_ids. This ensures that the file_id is accurately passed to the download handler, addressing a previously identified bug.
@danny-avila danny-avila force-pushed the fix/markdown-file-download-parsing branch from 265cd1d to 61a8d81 Compare November 14, 2025 18:41
@danny-avila danny-avila changed the base branch from main to dev November 14, 2025 18:41
@danny-avila danny-avila changed the title fix: correct file_id extraction in markdown file download links 🔗 fix: Correct file_id Extraction in Markdown File Download Links Nov 14, 2025
@danny-avila danny-avila changed the title 🔗 fix: Correct file_id Extraction in Markdown File Download Links 🔗 fix: Correct file_id Extraction in Markdown File Download Links Nov 14, 2025
@danny-avila
Copy link
Owner

I added a test to confirm what you're seeing but this is not intended usage, nor can I reproduce "downloading" the file, what is the use case here?

The ability to download files via markdown URL is considered legacy behavior for the now deprecated Assistants API integration

@danny-avila danny-avila marked this pull request as draft November 14, 2025 18:50
@bastianseipp
Copy link
Author

Thanks for reviewing! I understand this may not be the intended usage pattern. Here's my use case:

What I'm Doing

I'm building an MCP tool that generates documents (using Pandoc) from chat conversations. My workflow is:

  1. MCP tool creates a document based on user input
  2. Saves it to /app/uploads/{userId}/{filename}
  3. Creates a MongoDB file record with file_id, filepath, etc.
  4. Returns markdown link in tool output: [filename](files/{userId}/{file_id})
  5. AI includes this link in its response
  6. User attempts to download

What I Found

When clicking the link, the download fails with a 404. Debugging showed the API was being called with /api/files/download/{userId}/{userId} instead of /api/files/download/{userId}/{file_id}.

Tracing through MarkdownComponents.tsx, I found the extraction logic on lines 92-94 was using .pop() twice, which extracts values in reverse order from the array.

With My Fix

The download works correctly - my MCP tool can now generate and serve files through LibreChat's native download system.

Question

Is there a better/intended way to serve files generated by MCP tools to users? If the markdown download pattern is deprecated, I'm happy to implement whatever the recommended approach is. I couldn't find another way to make downloadable files work from external MCP tools without modifying LibreChat's codebase more broadly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants