Skip to content

📎 fix: Route Unrecognized File Types via supportedMimeTypes Config#12508

Merged
danny-avila merged 12 commits into
devfrom
claude/gracious-easley
Apr 2, 2026
Merged

📎 fix: Route Unrecognized File Types via supportedMimeTypes Config#12508
danny-avila merged 12 commits into
devfrom
claude/gracious-easley

Conversation

@danny-avila

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

Copy link
Copy Markdown
Owner

Summary

I fixed a silent failure where files with mime types not matching the hardcoded categories (image, PDF, video, audio) were dropped in BaseClient.processAttachments, never reaching the provider. The upload succeeded and the file appeared in the UI, but was never included in the API request.

  • Resolve the endpoint's supportedMimeTypes config from fileConfig inside processAttachments and check unrecognized file types against it before routing to the documents pipeline.
  • Guard file.type against null/undefined before calling checkType to prevent coercion to string 'null'/'undefined' with permissive patterns like '.*'.
  • Cache _mergedFileConfig and _endpointFileConfig on the instance so addPreviousAttachments doesn't recompute per historical message.
  • Use agent.endpoint (not agent.provider) for the getEndpointFileConfig lookup, matching the pattern in addDocuments and ensuring custom endpoint MIME configs are resolved correctly for agent runs.
  • Extract formatDocumentBlock helper to eliminate ~30 lines of duplicate provider-dispatch code between the PDF and generic encoding paths.
  • Add size validation in the generic encoding path using a base64 length formula (O(1), no heap allocation) against configuredFileSizeLimit.
  • Hoist configuredFileSizeLimit above the per-file loop to avoid recomputing mergeFileConfig on every iteration.
  • Pre-filter Bedrock files before fetching streams to avoid downloading unsupported types that would be discarded.
  • Guard Bedrock from the generic encoding path — non-bedrockDocumentFormats types are now skipped instead of silently tracking metadata with no document sent.
  • Only push metadata to result.files when a document block was actually created, preventing silent inconsistent state.
  • Enable Anthropic citations for text/plain, text/html, text/markdown (supported by Anthropic's document API).
  • Fix != to !== for Providers.AZURE comparison; use ?? instead of || for filename fallback.
  • Add JSDoc @type annotations for _mergedFileConfig and _endpointFileConfig in the constructor.

Closes #12482

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

  1. Configure a custom endpoint in librechat.yaml with broad supportedMimeTypes:
    fileConfig:
      endpoints:
        custom:
          supportedMimeTypes:
            - '.*'
  2. Upload a non-standard file type (e.g., .xlsx, .csv, .txt) to a conversation using that endpoint.
  3. Verify the file is encoded and included in the provider API request (previously silently dropped).
  4. Verify standard file types (images, PDFs, video, audio) continue routing through their dedicated pipelines.
  5. Verify that without supportedMimeTypes config matching the file type, unrecognized types are still skipped.
  6. Run cd packages/api && npx jest document processAttachments — 63 tests pass (40 existing + 9 encoding + 14 routing).

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • 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

Copilot AI review requested due to automatic review settings April 1, 2026 22:27
@danny-avila danny-avila changed the base branch from main to dev April 1, 2026 22:29

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 a silent attachment drop in the server message-building pipeline by ensuring previously “uncategorized” MIME types are still forwarded to providers, and additionally introduces an auth-aware startup config query key on the client to prevent stale unauthenticated config caching after login.

Changes:

  • Route unrecognized attachment MIME types through the documents pipeline in BaseClient.processAttachments so they’re encoded/sent instead of dropped.
  • Add startupConfigKey(isAuthenticated) and update multiple client call sites to use the new query key shape.
  • Adjust login/query enablement flow and update a unit test mock to preserve new data-provider exports.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
client/src/hooks/SSE/useEventHandlers.ts Uses new startupConfigKey when reading cached startup config during SSE handling.
client/src/hooks/Input/useQueryParams.ts Uses new startupConfigKey when reading cached startup config for query-param-driven behavior.
client/src/hooks/Input/useQueryParams.spec.ts Updates ~/data-provider mock strategy to preserve real exports like startupConfigKey.
client/src/hooks/Endpoint/useEndpoints.ts Changes interface config fallback to defaults and adds getConfigDefaults usage.
client/src/hooks/Conversations/useNavigateToConvo.tsx Uses new startupConfigKey when applying model spec effects on navigation.
client/src/hooks/Chat/useChatFunctions.ts Uses new startupConfigKey when building chat submission payloads.
client/src/hooks/AuthContext.tsx Re-enables queries via AuthContext after authentication state is applied.
client/src/data-provider/Endpoints/queries.ts Introduces startupConfigKey and updates useGetStartupConfig to use it.
client/src/data-provider/Auth/mutations.ts Disables queries during login mutation; re-enables on error and defers success re-enable to AuthContext.
client/src/components/Nav/SettingsTabs/Data/ImportConversations.tsx Uses new startupConfigKey when reading import size limits.
client/src/components/Chat/Menus/Endpoints/ModelSelector.tsx Hoists default interface config to a module constant.
api/app/clients/BaseClient.js Adds fallback categorization so unknown MIME types go through documents handling.

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

Comment on lines +26 to +33
/**
* Auth-aware query key so unauthenticated (login page) and authenticated
* (chat page) configs are cached independently, preventing stale
* unauthenticated config from persisting after login.
*/
export const startupConfigKey = (isAuthenticated: boolean) =>
[QueryKeys.startupConfig, isAuthenticated] as const;

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

PR description/title focus on routing unrecognized file types through the documents pipeline, but this file introduces a new auth-aware startupConfigKey and changes startup config caching behavior. Please either update the PR description to cover this behavioral change (and rationale/impact), or split it into a separate PR to keep review and risk scoped.

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +112
// Mock data-provider hooks while preserving real exports like startupConfigKey
jest.mock('~/data-provider', () => {
const actual = jest.requireActual<typeof import('~/data-provider')>('~/data-provider');
return {
...actual,
useGetAgentByIdQuery: jest.fn(() => ({
data: null,
isLoading: false,
error: null,
})),
useListAgentsQuery: jest.fn(() => ({
data: null,
isLoading: false,
error: null,
})),
};
});

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

This test now preserves the real startupConfigKey export, but the suite’s queryClient.getQueryData mock still appears to key off a plain 'startupConfig' string. Since production code now calls getQueryData(startupConfigKey(true)) (an array key), the mock should be updated to recognize the new key shape (or expose a mocked startupConfigKey that returns the old key) to avoid false negatives/failing tests.

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +112
// Mock data-provider hooks while preserving real exports like startupConfigKey
jest.mock('~/data-provider', () => {
const actual = jest.requireActual<typeof import('~/data-provider')>('~/data-provider');
return {
...actual,
useGetAgentByIdQuery: jest.fn(() => ({
data: null,
isLoading: false,
error: null,
})),
useListAgentsQuery: jest.fn(() => ({
data: null,
isLoading: false,
error: null,
})),
};
});

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

Using jest.requireActual('~/data-provider') in this mock will load the full data-provider module graph during the unit test, which can introduce side effects and makes the test more brittle (it depends on other mocks being set up correctly). Consider mocking only the needed exports (e.g., provide a lightweight startupConfigKey implementation alongside the hook mocks) instead of spreading the entire actual module.

Copilot uses AI. Check for mistakes.
@danny-avila danny-avila force-pushed the claude/gracious-easley branch from 19ed4cc to f31b6df Compare April 1, 2026 22:36
@danny-avila danny-avila marked this pull request as draft April 1, 2026 22:53
In processAttachments, files not matching the hardcoded mime type
categories (image, PDF, video, audio) were silently dropped. Now
resolves the endpoint's file config and checks the file type against
supportedMimeTypes before routing to the documents pipeline. Files
not matching any config are still skipped (original behavior).

Closes #12482
Remove restrictive mime type filter in encodeAndFormatDocuments that
only allowed PDFs and application/* types. Add a generic encoding
path for non-PDF, non-Bedrock files using the provider's native
format (Anthropic base64 document, OpenAI file block, Google media
block). Files are already validated upstream by supportedMimeTypes.
@danny-avila danny-avila force-pushed the claude/gracious-easley branch from f31b6df to 3ef63eb Compare April 1, 2026 23:10
@danny-avila danny-avila changed the title 📎 fix: Route Unrecognized File Types Through Documents Pipeline 📎 fix: Route Unrecognized File Types via supportedMimeTypes Config Apr 1, 2026
- Add file.type truthiness check before checkType to prevent
  coercion of null/undefined to string 'null'/'undefined'
- Cache mergedFileConfig and endpointFileConfig on the instance
  so addPreviousAttachments doesn't recompute per message
- Extract formatDocumentBlock helper to eliminate ~30 lines of
  duplicate provider-dispatch code between PDF and generic paths
- Add size validation in generic encoding path using
  configuredFileSizeLimit (was fetched but unused)
- Guard Bedrock from generic path — non-bedrockDocumentFormats
  types are now skipped instead of silently tracking metadata
- Only push metadata to result.files when a document block was
  actually created, preventing silent inconsistent state
- Enable Anthropic citations for text/plain, text/html,
  text/markdown (supported by Anthropic's document API)
- Fix != to !== for Providers.AZURE comparison
- Add 9 tests covering all four provider branches, Bedrock
  exclusion, size limit enforcement, and unhandled provider
filename parameter is string | undefined but OpenAIFileBlock and
OpenAIInputFileBlock require string. Default to 'document' when
filename is undefined.
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 361da1a7cb

ℹ️ 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".

Comment thread api/app/clients/BaseClient.js
Comment thread packages/api/src/files/encode/document.ts
Agent runs can have agent.provider set to a base provider (e.g.,
openAI) while agent.endpoint is a custom endpoint name. Using
provider for the getEndpointFileConfig lookup bypassed custom
endpoint supportedMimeTypes config. Now uses agent.endpoint,
matching the pattern in addDocuments.
Bedrock only supports types in bedrockDocumentFormats. Previously,
getFileStream was called for all files and unsupported types were
discarded after download. Now pre-filters the file list for Bedrock
to avoid unnecessary network and memory overhead for large
unsupported attachments.
@danny-avila danny-avila marked this pull request as ready for review April 2, 2026 02:14
- Remove redundant ?? null intermediaries; use instance properties
  directly in the else-if condition
- Add JSDoc @type annotations for _mergedFileConfig and
  _endpointFileConfig in the constructor
- Hoist configuredFileSizeLimit above the loop to avoid recomputing
  mergeFileConfig per file
- Replace Buffer.from decode with base64 length formula in the
  generic size check to avoid unnecessary heap allocation
- Use nullish coalescing (??) for filename fallback
- Clean up test: remove unnecessary type cast, use createMockRequest
  helper for size-limit test
- Add 14 tests for processAttachments categorization logic covering
  supportedMimeTypes routing, null/undefined guards, standard type
  passthrough, and edge cases
FileConfig.checkType is typed as optional. Use optional chaining
to satisfy strict type checking.
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b2cf1dce0

ℹ️ 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".

Comment thread packages/api/src/files/encode/document.ts
Comment thread api/app/clients/BaseClient.js
…eric routing

- Return early from encodeAndFormatDocuments when the provider is
  neither document-supported nor Bedrock, avoiding unnecessary
  getFileStream calls for providers that would discard all results
- Add !isBedrock guard to the supportedMimeTypes fallback branch in
  processAttachments so permissive patterns like '.*' don't route
  non-Bedrock types into documents that would be silently dropped
- Add test for Bedrock + non-Bedrock-document-type skipping
Remove !isBedrock guard from the generic supportedMimeTypes routing
branch. If a user configures permissive supportedMimeTypes for a
Bedrock endpoint, the upload validation already accepted the file.
The encoding layer pre-filters to Bedrock-supported types before
fetching streams, so unsupported types are handled there without
silently dropping files the user explicitly allowed.
@danny-avila

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c108f8a09

ℹ️ 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".

Comment thread api/app/clients/BaseClient.js
@danny-avila danny-avila merged commit 6ecd1b5 into dev Apr 2, 2026
10 checks passed
@danny-avila danny-avila deleted the claude/gracious-easley branch April 2, 2026 03:04
yidianyiko pushed a commit to yidianyiko/LibreChat that referenced this pull request Apr 13, 2026
…anny-avila#12508)

* fix: check supportedMimeTypes before routing unrecognized file types

In processAttachments, files not matching the hardcoded mime type
categories (image, PDF, video, audio) were silently dropped. Now
resolves the endpoint's file config and checks the file type against
supportedMimeTypes before routing to the documents pipeline. Files
not matching any config are still skipped (original behavior).

Closes danny-avila#12482

* feat: encode generic document types for supported providers

Remove restrictive mime type filter in encodeAndFormatDocuments that
only allowed PDFs and application/* types. Add a generic encoding
path for non-PDF, non-Bedrock files using the provider's native
format (Anthropic base64 document, OpenAI file block, Google media
block). Files are already validated upstream by supportedMimeTypes.

* fix: guard file.type and cache file config in processAttachments

- Add file.type truthiness check before checkType to prevent
  coercion of null/undefined to string 'null'/'undefined'
- Cache mergedFileConfig and endpointFileConfig on the instance
  so addPreviousAttachments doesn't recompute per message

* refactor: harden generic document encoding with validation and tests

- Extract formatDocumentBlock helper to eliminate ~30 lines of
  duplicate provider-dispatch code between PDF and generic paths
- Add size validation in generic encoding path using
  configuredFileSizeLimit (was fetched but unused)
- Guard Bedrock from generic path — non-bedrockDocumentFormats
  types are now skipped instead of silently tracking metadata
- Only push metadata to result.files when a document block was
  actually created, preventing silent inconsistent state
- Enable Anthropic citations for text/plain, text/html,
  text/markdown (supported by Anthropic's document API)
- Fix != to !== for Providers.AZURE comparison
- Add 9 tests covering all four provider branches, Bedrock
  exclusion, size limit enforcement, and unhandled provider

* fix: resolve filename type mismatch in formatDocumentBlock

filename parameter is string | undefined but OpenAIFileBlock and
OpenAIInputFileBlock require string. Default to 'document' when
filename is undefined.

* fix: use endpoint name for file config lookup in processAttachments

Agent runs can have agent.provider set to a base provider (e.g.,
openAI) while agent.endpoint is a custom endpoint name. Using
provider for the getEndpointFileConfig lookup bypassed custom
endpoint supportedMimeTypes config. Now uses agent.endpoint,
matching the pattern in addDocuments.

* perf: filter non-Bedrock files before fetching streams

Bedrock only supports types in bedrockDocumentFormats. Previously,
getFileStream was called for all files and unsupported types were
discarded after download. Now pre-filters the file list for Bedrock
to avoid unnecessary network and memory overhead for large
unsupported attachments.

* refactor: clean up processAttachments file config handling

- Remove redundant ?? null intermediaries; use instance properties
  directly in the else-if condition
- Add JSDoc @type annotations for _mergedFileConfig and
  _endpointFileConfig in the constructor

* refactor: harden document encoding and add routing tests

- Hoist configuredFileSizeLimit above the loop to avoid recomputing
  mergeFileConfig per file
- Replace Buffer.from decode with base64 length formula in the
  generic size check to avoid unnecessary heap allocation
- Use nullish coalescing (??) for filename fallback
- Clean up test: remove unnecessary type cast, use createMockRequest
  helper for size-limit test
- Add 14 tests for processAttachments categorization logic covering
  supportedMimeTypes routing, null/undefined guards, standard type
  passthrough, and edge cases

* fix: use optional chaining for checkType in routing tests

FileConfig.checkType is typed as optional. Use optional chaining
to satisfy strict type checking.

* fix: skip stream fetches for unsupported providers, block Bedrock generic routing

- Return early from encodeAndFormatDocuments when the provider is
  neither document-supported nor Bedrock, avoiding unnecessary
  getFileStream calls for providers that would discard all results
- Add !isBedrock guard to the supportedMimeTypes fallback branch in
  processAttachments so permissive patterns like '.*' don't route
  non-Bedrock types into documents that would be silently dropped
- Add test for Bedrock + non-Bedrock-document-type skipping

* fix: respect supportedMimeTypes config for Bedrock endpoints

Remove !isBedrock guard from the generic supportedMimeTypes routing
branch. If a user configures permissive supportedMimeTypes for a
Bedrock endpoint, the upload validation already accepted the file.
The encoding layer pre-filters to Bedrock-supported types before
fetching streams, so unsupported types are handled there without
silently dropping files the user explicitly allowed.
jcbartle pushed a commit to jcbartle/LibreChat that referenced this pull request May 11, 2026
…anny-avila#12508)

* fix: check supportedMimeTypes before routing unrecognized file types

In processAttachments, files not matching the hardcoded mime type
categories (image, PDF, video, audio) were silently dropped. Now
resolves the endpoint's file config and checks the file type against
supportedMimeTypes before routing to the documents pipeline. Files
not matching any config are still skipped (original behavior).

Closes danny-avila#12482

* feat: encode generic document types for supported providers

Remove restrictive mime type filter in encodeAndFormatDocuments that
only allowed PDFs and application/* types. Add a generic encoding
path for non-PDF, non-Bedrock files using the provider's native
format (Anthropic base64 document, OpenAI file block, Google media
block). Files are already validated upstream by supportedMimeTypes.

* fix: guard file.type and cache file config in processAttachments

- Add file.type truthiness check before checkType to prevent
  coercion of null/undefined to string 'null'/'undefined'
- Cache mergedFileConfig and endpointFileConfig on the instance
  so addPreviousAttachments doesn't recompute per message

* refactor: harden generic document encoding with validation and tests

- Extract formatDocumentBlock helper to eliminate ~30 lines of
  duplicate provider-dispatch code between PDF and generic paths
- Add size validation in generic encoding path using
  configuredFileSizeLimit (was fetched but unused)
- Guard Bedrock from generic path — non-bedrockDocumentFormats
  types are now skipped instead of silently tracking metadata
- Only push metadata to result.files when a document block was
  actually created, preventing silent inconsistent state
- Enable Anthropic citations for text/plain, text/html,
  text/markdown (supported by Anthropic's document API)
- Fix != to !== for Providers.AZURE comparison
- Add 9 tests covering all four provider branches, Bedrock
  exclusion, size limit enforcement, and unhandled provider

* fix: resolve filename type mismatch in formatDocumentBlock

filename parameter is string | undefined but OpenAIFileBlock and
OpenAIInputFileBlock require string. Default to 'document' when
filename is undefined.

* fix: use endpoint name for file config lookup in processAttachments

Agent runs can have agent.provider set to a base provider (e.g.,
openAI) while agent.endpoint is a custom endpoint name. Using
provider for the getEndpointFileConfig lookup bypassed custom
endpoint supportedMimeTypes config. Now uses agent.endpoint,
matching the pattern in addDocuments.

* perf: filter non-Bedrock files before fetching streams

Bedrock only supports types in bedrockDocumentFormats. Previously,
getFileStream was called for all files and unsupported types were
discarded after download. Now pre-filters the file list for Bedrock
to avoid unnecessary network and memory overhead for large
unsupported attachments.

* refactor: clean up processAttachments file config handling

- Remove redundant ?? null intermediaries; use instance properties
  directly in the else-if condition
- Add JSDoc @type annotations for _mergedFileConfig and
  _endpointFileConfig in the constructor

* refactor: harden document encoding and add routing tests

- Hoist configuredFileSizeLimit above the loop to avoid recomputing
  mergeFileConfig per file
- Replace Buffer.from decode with base64 length formula in the
  generic size check to avoid unnecessary heap allocation
- Use nullish coalescing (??) for filename fallback
- Clean up test: remove unnecessary type cast, use createMockRequest
  helper for size-limit test
- Add 14 tests for processAttachments categorization logic covering
  supportedMimeTypes routing, null/undefined guards, standard type
  passthrough, and edge cases

* fix: use optional chaining for checkType in routing tests

FileConfig.checkType is typed as optional. Use optional chaining
to satisfy strict type checking.

* fix: skip stream fetches for unsupported providers, block Bedrock generic routing

- Return early from encodeAndFormatDocuments when the provider is
  neither document-supported nor Bedrock, avoiding unnecessary
  getFileStream calls for providers that would discard all results
- Add !isBedrock guard to the supportedMimeTypes fallback branch in
  processAttachments so permissive patterns like '.*' don't route
  non-Bedrock types into documents that would be silently dropped
- Add test for Bedrock + non-Bedrock-document-type skipping

* fix: respect supportedMimeTypes config for Bedrock endpoints

Remove !isBedrock guard from the generic supportedMimeTypes routing
branch. If a user configures permissive supportedMimeTypes for a
Bedrock endpoint, the upload validation already accepted the file.
The encoding layer pre-filters to Bedrock-supported types before
fetching streams, so unsupported types are handled there without
silently dropping files the user explicitly allowed.
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.

[Bug]: Upload to provider fails silently for file types not included in hardcoded list of allowed types

2 participants