Skip to content

📂 fix: Preserve Nested Skill Paths in Code-Env Uploads#12877

Merged
danny-avila merged 2 commits into
devfrom
fix/code-env-preserve-filepaths
Apr 29, 2026
Merged

📂 fix: Preserve Nested Skill Paths in Code-Env Uploads#12877
danny-avila merged 2 commits into
devfrom
fix/code-env-preserve-filepaths

Conversation

@danny-avila

@danny-avila danny-avila commented Apr 29, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the LibreChat half of nested code-environment file uploads. Skill priming builds filenames like pptx/pptx.py, but the Node form-data string overload silently converts that to filename="pptx.py" before CodeAPI receives the multipart request.

The new backend logic lives in packages/api: appendCodeEnvFile uses the form-data filepath option for path-bearing names so the multipart filename remains pptx/pptx.py. The legacy /api upload service only imports that package helper and applies it to single-file and batch CodeEnv uploads.

CodeAPI already has busboy({ preservePath: true }), header encoding, RFC 5987 download parsing, and recursive sandbox placement, so this lets the existing server-side path preservation finally see the path LibreChat intended to send.

Root Cause

form.append("file", stream, "pptx/pptx.py") does not send that string verbatim. In form-data, the bare string overload is treated as options.filename and passed through path.basename, producing:

Content-Disposition: form-data; name="file"; filename="pptx.py"

Using filepath produces the path-bearing multipart header CodeAPI expects:

Content-Disposition: form-data; name="file"; filename="pptx/pptx.py"

Without this, skill helper modules still land flat at /mnt/data/pptx.py and can shadow installed packages like python-pptx.

Changes

  • Add a TypeScript CodeEnv FormData helper in packages/api/src/files/code/form.ts that uses { filename, filepath } for nested filenames and normalizes Windows separators.
  • Export the helper from @librechat/api and keep /api/server/services/Files/Code/crud.js as the thin legacy caller.
  • Add regression coverage showing the bare string overload strips paths and the package helper preserves them.

Test Plan

  • cd packages/api && npx jest src/files/code/form.spec.ts --runInBand
  • cd api && npx jest server/services/Files/Code/crud.spec.js --runInBand
  • cd packages/api && npm run build
  • npx eslint packages/api/src/files/code/form.ts packages/api/src/files/code/form.spec.ts api/server/services/Files/Code/crud.js api/server/services/Files/Code/crud.spec.js
  • Local integration: prime the pptx skill and confirm /mnt/data/pptx/pptx.py exists while /mnt/data/pptx.py does not.

Related

Pairs with ClickHouse/ai#1358 for CodeAPI-side internal header hardening.

Copilot AI review requested due to automatic review settings April 29, 2026 11:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Code Environment uploads so multipart filenames preserve nested paths (e.g. pptx/pptx.py) by using form-data’s filepath option, allowing the existing CodeAPI preservePath handling to place files into the expected subdirectories.

Changes:

  • Introduce a small FormData helper for CodeEnv uploads that uses { filename, filepath } when a filename contains path separators (and normalizes Windows \ to /).
  • Switch both single-file and batch CodeEnv upload flows to use the helper.
  • Add regression tests proving the form.append(..., 'dir/file') string overload strips directories while the helper preserves them.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
api/server/services/Files/Code/formData.js Adds helper to build form-data options for path-preserving CodeEnv uploads.
api/server/services/Files/Code/crud.js Uses the helper for single and batch CodeEnv uploads.
api/server/services/Files/Code/formData.spec.js Adds tests asserting the multipart filename header preserves nested paths with filepath.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +22
function getCodeEnvFileOptions(filename) {
const normalized = filename.replace(/\\/g, '/');
const basename = path.posix.basename(normalized);

if (normalized !== basename) {
return { filename: basename, filepath: normalized };
}

return { filename };

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getCodeEnvFileOptions forwards any path-bearing filename verbatim via filepath (after only replacing \\ with /). Since uploadCodeEnvFile can receive filename from multer's file.originalname (user-controlled), this enables sending ../ segments, absolute paths (/etc/passwd), or Windows drive paths (C:/...) to CodeAPI once path preservation is enabled. Please sanitize/validate the path before returning it (e.g., reuse sanitizeArtifactPath from @librechat/api, strip leading slashes / drive prefixes, and reject .. segments), and add a small regression test for traversal/absolute-path inputs so this doesn't become a sandbox path traversal vector if CodeAPI-side protections regress.

Copilot uses AI. Check for mistakes.
@github-actions

Copy link
Copy Markdown
Contributor

GitNexus: 🚀 deployed

The LibreChat-pr-12877 index is now live on the MCP server.
Deploy run

@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila danny-avila force-pushed the fix/code-env-preserve-filepaths branch from 53c4276 to 65fd57a Compare April 29, 2026 11:50
@github-actions

Copy link
Copy Markdown
Contributor

GitNexus: 🚀 deployed

The LibreChat-pr-12877 index is now live on the MCP server.
Deploy run

@github-actions

Copy link
Copy Markdown
Contributor

GitNexus: 🚀 deployed

The LibreChat-pr-12877 index is now live on the MCP server.
Deploy run

@danny-avila danny-avila merged commit 4a5fc70 into dev Apr 29, 2026
11 checks passed
@danny-avila danny-avila deleted the fix/code-env-preserve-filepaths branch April 29, 2026 12:07
fuuuzzy pushed a commit to fuuuzzy/LibreChat that referenced this pull request May 3, 2026
…2877)

* fix(code): preserve code env upload filepaths

* chore: Reorder import statements in crud.js
jcbartle pushed a commit to jcbartle/LibreChat that referenced this pull request May 11, 2026
…2877)

* fix(code): preserve code env upload filepaths

* chore: Reorder import statements in crud.js
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