Skip to content

(feat/fix) [RHDHBUGS- 3302] using Markitdown for AI notebooks - #4020

Open
JslYoon wants to merge 10 commits into
redhat-developer:mainfrom
JslYoon:worktree-docling-notebooks
Open

(feat/fix) [RHDHBUGS- 3302] using Markitdown for AI notebooks#4020
JslYoon wants to merge 10 commits into
redhat-developer:mainfrom
JslYoon:worktree-docling-notebooks

Conversation

@JslYoon

@JslYoon JslYoon commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the custom per-format file parser (fileParser.ts) with markitdown-ts for converting uploaded documents to markdown before vectorization in AI notebooks.

Why

The previous implementation maintained separate parsing logic for each file type (txt, md, json, yaml, pdf) using pdfjs-dist, js-yaml, and manual text extraction. markitdown-ts handles all of these with a single library, reducing maintenance surface and improving conversion quality — especially for PDFs and rich document formats.

What changed

  • Removed fileParser.ts (224 lines) and its 541-line test suite — custom per-format parsing logic (text, JSON, YAML, PDF)
  • Removed parseFileContent and stripHtmlTags from documentHelpers.ts — no longer needed since markitdown handles conversion
  • Added markitdownClient.ts — thin wrapper around markitdown-ts that:
    • Passes plaintext formats (json, yaml, yml, log) through as-is
    • Routes all other formats (pdf, md, txt, etc.) through markitdown-ts for markdown conversion
    • Validates file extension matches declared type
  • Added markitdownClient.test.ts — 17 unit tests covering plaintext passthrough, markitdown conversion, extension mismatch errors, and empty output handling (100% coverage)
  • Updated documentService.ts and notebooksRouters.ts to use convertToMarkdown instead of the old parseFile pipeline
  • Updated dependencies: added markitdown-ts, removed pdfjs-dist and js-yaml

Impact

  • Simpler document ingestion path: upload → markitdown → markdown → vectorize
  • Fewer dependencies to maintain
  • Better conversion quality for complex document formats

✔️ Checklist

https://redhat.atlassian.net/browse/RHDHBUGS-3302

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

@rhdh-gh-app

rhdh-gh-app Bot commented Jul 27, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Unexpected Changesets

The following changeset(s) reference packages that have not been changed in this PR:

  • /home/runner/work/rhdh-plugins/rhdh-plugins/workspaces/intelligent-assistant/.changeset/fuzzy-peaches-shake.md: @red-hat-developer-hub/backstage-plugin-lightspeed-backend

Note that only changes that affect the published package require changesets, for example changes to tests and storybook stories do not require changesets.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend workspaces/intelligent-assistant/plugins/intelligent-assistant-backend minor v3.2.0

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

AI Notebooks: convert uploads to Markdown with markitdown before vectorizing

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Convert uploaded notebook documents to Markdown via markitdown before vectorization.
• Upload converted content as .md (text/markdown) to the Files API.
• Add markitdown-ts dependency and changesets for notebook-related releases.
Diagram

graph TD
  C[Client] --> R["Notebooks router"] --> M["Markdown conversion"] --> F[("Files API")] --> U["Vector store upsert"] --> V[("Vector store")]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pass-through for .md/.txt (convert only rich formats)
  • ➕ Avoids unnecessary conversion work/latency for already-text inputs
  • ➕ Reduces risk of conversion altering plain text semantics
  • ➖ Slightly more branching logic; must define what is considered safe pass-through
2. Reuse existing parseFileContent pipeline for size/type enforcement
  • ➕ Keeps a single, consistent validation path (size limits, parsing errors)
  • ➕ Leverages existing tests around file parsing
  • ➖ May duplicate work if markitdown becomes the canonical converter
  • ➖ Requires deciding how parseFileContent and markitdown interact for PDFs
3. Move markdown conversion to the background job
  • ➕ Faster HTTP response and less chance of request timeouts for large PDFs
  • ➕ Makes the request handler simpler and more resilient
  • ➖ Requires persisting the original upload (or buffering) before conversion
  • ➖ More complex failure/status reporting (conversion failures become async)

Recommendation: The PR’s approach (normalize to Markdown before vectorization) is a solid direction for retrieval quality/performance. Consider extending plaintext passthrough to .md/.txt (and possibly other known-text types) and/or reusing existing file-size validation to avoid accidental regression in upload constraints; moving conversion async is optional depending on observed request latency for PDFs.

Files changed (7) +618 / -21

Enhancement (3) +75 / -17
documentService.tsUpload Markdown files to Files API (text/markdown) +9/-11

Upload Markdown files to Files API (text/markdown)

• Changes document uploads to always send Markdown content as a .md file with MIME type text/markdown. Removes the previous toFile-based upload wrapper and simplifies the file payload structure.

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/documentService.ts

markitdownClient.tsAdd MarkItDown client wrapper for buffer → Markdown conversion +53/-0

Add MarkItDown client wrapper for buffer → Markdown conversion

• Adds convertToMarkdown(buffer, originalName) using markitdown-ts, with plaintext passthrough for json/yaml/yml/log. Throws an InputError when conversion produces no Markdown output.

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/markitdownClient.ts

notebooksRouters.tsConvert uploaded document to Markdown before vector-store upsert +13/-6

Convert uploaded document to Markdown before vector-store upsert

• Replaces the previous parseFileContent flow with a markitdown-based conversion step, then uploads the Markdown to the Files API. Adds an explicit guard for missing req.file and updates wording to reflect attaching a file to the vector store in the background.

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/notebooksRouters.ts

Other (4) +543 / -4
fuzzy-peaches-shake.mdAdd changeset for notebooks 404 passthrough bugfix release +5/-0

Add changeset for notebooks 404 passthrough bugfix release

• Adds a changeset entry to publish a minor release for the lightspeed backend plugin, documenting a notebooks route 404 passthrough fix.

workspaces/intelligent-assistant/.changeset/fuzzy-peaches-shake.md

six-chairs-turn.mdAdd changeset documenting Markdown cleanup before vectorization +5/-0

Add changeset documenting Markdown cleanup before vectorization

• Adds a changeset entry to publish a minor release for the intelligent-assistant backend plugin, documenting the switch to Markdown cleanup before vectorization.

workspaces/intelligent-assistant/.changeset/six-chairs-turn.md

package.jsonAdd markitdown-ts dependency for document-to-Markdown conversion +1/-0

Add markitdown-ts dependency for document-to-Markdown conversion

• Introduces markitdown-ts as a runtime dependency to support converting uploaded documents into Markdown prior to ingestion.

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/package.json

yarn.lockLockfile updates for markitdown-ts transitive dependencies +532/-4

Lockfile updates for markitdown-ts transitive dependencies

• Updates the workspace lockfile to include markitdown-ts and its transitive dependency graph (including document parsing/conversion libraries).

workspaces/intelligent-assistant/yarn.lock

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jul 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. FileType ignored in conversion ✓ Resolved 🐞 Bug ≡ Correctness
Description
The documents upload route validates req.body.fileType, but convertToMarkdown derives
file_extension only from req.file.originalname, so extensionless or mismatched filenames can be
converted with the wrong/empty type and fail or produce incorrect markdown before vectorization.
This is a regression from the previous parsing flow that used the validated fileType to drive
parsing.
Code

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/notebooksRouters.ts[R408-412]

+      const markdown = await convertToMarkdown(
+        req.file.buffer,
+        req.file.originalname,
      );
+      const fileId = await documentService.uploadFile(markdown, title);
Relevance

●●● Strong

Likely regression: team historically emphasizes consistent notebook file-type validation and upload
correctness.

PR-#3104
PR-#2499

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The router validates fileType but does not pass it into conversion; conversion determines
file_extension solely from originalName, while the previous parsing utilities in this codebase
explicitly take fileType to drive parsing behavior.

workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/notebooksRouters.ts[374-428]
workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/markitdownClient.ts[29-45]
workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/documentHelpers.ts[88-103]
workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/fileParser.ts[169-196]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The upload endpoint validates `fileType` but conversion uses `req.file.originalname` to infer the extension, which can be empty or disagree with `fileType`. This can cause markitdown to convert using the wrong file format (or no format) and break otherwise-valid requests.

## Issue Context
Previously, parsing used `fileType` (`parseFileContent(..., fileType, ...)` → `parseFile(..., fileType)`), so behavior was consistent with the validated request field.

## Fix Focus Areas
- workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/notebooksRouters.ts[374-429]
- workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/markitdownClient.ts[29-45]

### Suggested approach
1. Change `convertToMarkdown` signature to accept `fileType` (validated) and use it as the authoritative extension (e.g., `ext = '.' + normalizedFileType`).
2. Optionally compare the filename extension (if present) to `fileType` and reject with `InputError` when they disagree (or fall back to `fileType` when missing).
3. Update the router to call `convertToMarkdown(req.file.buffer, req.file.originalname, fileType)`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Compliance rules (platform): 11 rules
✅ Cross-repo context
  Explored: repo: redhat-developer/rhdh-operator (sha: 095451d9)
  Explored: repo: redhat-developer/rhdh-local (sha: 2ae9e8c8)
  Explored: repo: redhat-developer/rhdh (sha: 6bcb0141)
  Not relevant to this PR: redhat-developer/rhdh-chart

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added the enhancement New feature or request label Jul 27, 2026
@JslYoon JslYoon changed the title Worktree docling notebooks [RHDHBUGS- 3302] using Markitdown for AI notebooks Jul 27, 2026
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.59259% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.01%. Comparing base (0f32982) to head (02e47c4).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4020      +/-   ##
==========================================
- Coverage   58.11%   58.01%   -0.11%     
==========================================
  Files        2422     2411      -11     
  Lines       96484    96226     -258     
  Branches    26885    26770     -115     
==========================================
- Hits        56075    55828     -247     
- Misses      38914    40209    +1295     
+ Partials     1495      189    -1306     
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from 6dd0e73
ai-integrations 69.76% <ø> (ø) Carriedforward from 6dd0e73
app-defaults 69.79% <ø> (ø) Carriedforward from 6dd0e73
augment 46.67% <ø> (ø) Carriedforward from 6dd0e73
boost 76.77% <ø> (ø) Carriedforward from 6dd0e73
bulk-import 72.56% <ø> (ø) Carriedforward from 6dd0e73
cost-management 13.55% <ø> (ø) Carriedforward from 6dd0e73
dcm 60.72% <ø> (ø) Carriedforward from 6dd0e73
extensions 56.59% <ø> (ø) Carriedforward from 6dd0e73
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 6dd0e73
global-header 66.50% <ø> (ø) Carriedforward from 6dd0e73
homepage 47.59% <ø> (ø) Carriedforward from 6dd0e73
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from 6dd0e73
intelligent-assistant 74.50% <92.59%> (-0.09%) ⬇️
konflux 91.98% <ø> (ø) Carriedforward from 6dd0e73
lightspeed 69.02% <ø> (ø) Carriedforward from 6dd0e73
mcp-integrations 83.40% <ø> (ø) Carriedforward from 6dd0e73
orchestrator 66.87% <ø> (ø) Carriedforward from 6dd0e73
quickstart 63.67% <ø> (-0.08%) ⬇️ Carriedforward from 6dd0e73
sandbox 79.56% <ø> (ø) Carriedforward from 6dd0e73
scorecard 85.27% <ø> (-0.71%) ⬇️ Carriedforward from 6dd0e73
theme 88.52% <ø> (-0.25%) ⬇️ Carriedforward from 6dd0e73
translations 5.12% <ø> (ø) Carriedforward from 6dd0e73
x2a 79.20% <ø> (ø) Carriedforward from 6dd0e73

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0f32982...02e47c4. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JslYoon
JslYoon requested review from Jdubrick and maysunfaisal and removed request for Eswaraiahsapram and asmasarw July 28, 2026 17:44
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [changeset-target-error] workspaces/intelligent-assistant/.changeset/fuzzy-peaches-shake.md:2 — Changeset targets @red-hat-developer-hub/backstage-plugin-lightspeed-backend, which is not a package in this repository. The actual package is @red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend (per package.json). This changeset will either be silently ignored by the changesets tool (no version bump, no changelog entry) or cause a build error during release.
    Remediation: Change the package name in the changeset to @red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend.

Medium

  • [Input validation regression] workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/notebooksRouters.ts:402 — The PR removes the explicit isValidFileSize(file.size) check that was in the removed parseFileContent(). While multer's limits.fileSize config enforces the same 20MB limit at the transport layer, the application-layer defense-in-depth validation is removed.
    Remediation: If defense-in-depth is desired, re-add the explicit file size check before calling convertToMarkdown().

  • [Denial of service via untrusted content parsing] workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/markitdownClient.ts:31markitdown-ts v0.0.10 is an early-stage package with heavyweight transitive dependencies (jsdom, mammoth, pdf-parse, xlsx) that process user-supplied file buffers. The convertBuffer call has no timeout or resource limits. A crafted file within multer's size limit could still cause excessive memory/CPU usage during conversion.
    Remediation: Add a timeout wrapper around convertBuffer() (e.g., Promise.race with a 30-second timeout). Consider pinning the exact version rather than using ^0.0.10.

  • [error handling idiom] workspaces/intelligent-assistant/plugins/intelligent-assistant-backend/src/service/notebooks/documents/markitdownClient.ts:33 — Exceptions from markitdown.convertBuffer() propagate as-is (untyped library errors). The removed fileParser.ts wrapped every parser error in InputError, which Backstage maps to HTTP 400. If markitdown-ts throws a generic Error, it will surface as HTTP 500 instead of 400 to the client.
    Remediation: Wrap the convertBuffer call in a try/catch and re-throw as InputError: try { ... } catch (error) { throw new InputError(\Failed to convert ${originalName}: ${error}`); }`

Low

  • [test adequacy] markitdownClient.test.ts — No test covers when convertBuffer rejects with an exception. All failure-path tests only cover resolved-value paths (null, empty markdown, undefined).
  • [Input validation regression] markitdownClient.ts:29 — JSON/YAML format validation removed. The old fileParser.ts validated JSON (JSON.parse) and YAML (yaml.load) before passing through. The new code treats these as plaintext with no validation. This is a defensible simplification if downstream consumers handle arbitrary text.
  • [Filename injection] markitdownClient.ts:42 — User-controlled originalName (from req.file.originalname) is interpolated into error messages without sanitization. Low risk since Backstage returns InputError as structured JSON, but could enable log injection.
  • [Prompt injection defense gap] notebooksRouters.ts:405sanitizeContentForRAG() exists in documentHelpers.ts but is not called on converted markdown before upload. Pre-existing gap, not a regression introduced by this PR.
  • [Incomplete file extension validation] markitdownClient.ts:20 — Extension mismatch check is bypassed for filenames without dots (e.g., Makefile). The isValidFileType check in the router mitigates arbitrary type injection.
  • [scope-ambiguity] fuzzy-peaches-shake.md — PR title uses (feat/fix). The changeset claims "bugfix - Notebooks routes 404 passthrough error resolved" but no 404-related code changes are visible in the diff.
  • [coherence] documentHelpers.ts — Removes stripHtmlTags which was marked @reserved for future URL file type support. Constants HTML_BLOCK_TAGS and HTML_IGNORED_TAGS in constant.ts may become orphaned dead code.
  • [instantiation pattern] markitdownClient.ts:21 — Module-level singleton const markitdown = new MarkItDown() is instantiated at import time. Consider lazy initialization for consistency with codebase patterns.
  • [JSDoc convention] markitdownClient.ts:28 — Exported function convertToMarkdown lacks @param and @returns JSDoc tags used by other exported functions in this package.
  • [naming convention] markitdownClient.ts — File named markitdownClient but exports a standalone function, not a client class. Consider markdownConverter.ts or folding into documentHelpers.ts.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Reason: stale-head

The review agent reviewed commit 46460bdfa1af1070f9d71a5f8fd39fab84c43c4b but the PR HEAD is now ee493a299ad474a32f8c12eb6605205a626e38c9. This review was discarded to avoid approving unreviewed code.

@fullsend-ai-review

Copy link
Copy Markdown

/fs-review

@JslYoon
JslYoon force-pushed the worktree-docling-notebooks branch 2 times, most recently from 325de76 to 559cb4f Compare July 28, 2026 19:55
@JslYoon

JslYoon commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

/fs-review

JslYoon and others added 7 commits August 3, 2026 17:29
Signed-off-by: Lucas <lyoon@redhat.com>
Signed-off-by: Lucas <lyoon@redhat.com>
Signed-off-by: Lucas <lyoon@redhat.com>
Signed-off-by: Lucas <lyoon@redhat.com>
Signed-off-by: Lucas <lyoon@redhat.com>
Comment on lines +1 to +5
---
'@red-hat-developer-hub/backstage-plugin-lightspeed-backend': minor
---

bugfix - Notebooks routes 404 passthrough error resolved

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.

Are we including this bug fix in this PR and I have missed it? Or is this leftover and needs to be removed to avoid another minor bump?

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.

Lets remove this changeset if it is unused/not included in this PR to keep a clean history

@@ -0,0 +1,5 @@
---
'@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend': minor

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.

I think this should be a patch if it is a bugfix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I would say this is more of an enhancement, so that's why I put it as update, because I'm switching out a component to improve vector stores

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.

I'm on the side of if it isn't client facing / just internal then it should be a 'patch' but I will leave it up to you

JslYoon and others added 3 commits August 4, 2026 16:17
Cover plaintext passthrough, markitdown conversion, extension
mismatch validation, and empty output error handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

@Jdubrick

Jdubrick commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:34 PM UTC · Completed 1:54 PM UTC
Commit: 02e47c4 · View workflow run →

@fullsend-ai-review fullsend-ai-review 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.

See the review comment for full details.

@@ -0,0 +1,5 @@
---
'@red-hat-developer-hub/backstage-plugin-lightspeed-backend': minor

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[high] changeset-target-error

Changeset targets '@red-hat-developer-hub/backstage-plugin-lightspeed-backend', which is not a package in this repository. The actual package is '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend'. This changeset will either be silently ignored or cause a build error during release.

Suggested fix: Change the package name in the changeset to '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend'.


if (!req.file) {
handleError(logger, res, 'No file uploaded');
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] Input validation regression

The PR removes the explicit isValidFileSize(file.size) check that was in the removed parseFileContent(). While multer's limits.fileSize config enforces the same 20MB limit at the transport layer, the application-layer defense-in-depth validation is removed.

Suggested fix: If defense-in-depth is desired, re-add the explicit file size check before calling convertToMarkdown().

*/
export async function convertToMarkdown(
buffer: Buffer,
originalName: string,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] Denial of service via untrusted content parsing

markitdown-ts v0.0.10 is an early-stage package with heavyweight transitive dependencies (jsdom, mammoth, pdf-parse, xlsx) that process user-supplied file buffers. The convertBuffer call has no timeout or resource limits.

Suggested fix: Add a timeout wrapper around convertBuffer() (e.g., Promise.race with a 30-second timeout). Consider pinning the exact version.

buffer: Buffer,
originalName: string,
fileType: string,
): Promise<string> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] error handling idiom

Exceptions from markitdown.convertBuffer() propagate as-is. The removed fileParser.ts wrapped parsing errors in InputError (HTTP 400). If markitdown-ts throws a generic Error, it will surface as HTTP 500 instead of 400.

Suggested fix: Wrap the convertBuffer call in try/catch and re-throw as InputError.

* Convert a document buffer to markdown using markitdown-ts.
* Plain-text formats (json, yaml, log) are passed through as-is.
*/
export async function convertToMarkdown(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] Input validation regression

JSON/YAML format validation removed. The old fileParser.ts validated JSON (JSON.parse) and YAML (yaml.load) before passing through. The new code treats these as plaintext with no validation.

: '';
if (nameExt && nameExt !== ext) {
throw new InputError(
`File extension "${nameExt}" does not match declared file type "${fileType}"`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] Filename injection into error messages

User-controlled originalName interpolated into error messages without sanitization. Low risk since Backstage returns InputError as structured JSON.

return;
}

const markdown = await convertToMarkdown(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] Prompt injection defense gap

sanitizeContentForRAG() exists but is not called on converted markdown before upload. Pre-existing gap, not a regression.


import { MarkItDown } from 'markitdown-ts';

const markitdown = new MarkItDown();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] instantiation pattern

Module-level singleton instantiated at import time. Consider lazy initialization for consistency with codebase patterns.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants