Skip to content

fix: validate req.body.code in compileResume middleware (#1622) - #1722

Open
suhaniiz wants to merge 4 commits into
Canopus-Labs:mainfrom
suhaniiz:fix/1622-compile-resume-validation
Open

fix: validate req.body.code in compileResume middleware (#1622)#1722
suhaniiz wants to merge 4 commits into
Canopus-Labs:mainfrom
suhaniiz:fix/1622-compile-resume-validation

Conversation

@suhaniiz

@suhaniiz suhaniiz commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

📝 Pull Request Description

Related Issue

Closes #1622

Summary

Fixes an issue where POST /api/resume/compile returned a 500 Internal Server Error instead of a 400 Bad Request when req.body or req.body.code was missing or undefined.

Updated the validation middleware to use Zod's safeParse with an (req.body || {}) fallback, ensuring missing body payloads are caught early and handled gracefully with proper standard 400 validation error responses.


Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature
  • ♻️ Refactoring
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • 🔥 Other(please describe) ______

How Has This Been Tested?

  • Sent POST requests to /api/resume/compile with an empty JSON payload {} and confirmed it returns 400 Bad Request with {"message": "LaTeX code is required"} instead of throwing an unhandled TypeError.
  • Verified valid LaTeX code payloads pass schema validation as expected.
  • Verified non-string code payloads (e.g. {"code": 123}) trigger proper Zod validation error messages.

Screenshots (if applicable)

N/A


Checklist

  • My code follows the project's guidelines
  • I have tested my changes
  • I have updated documentation where necessary
  • I have linked the related issue
  • My changes do not introduce new warnings or errors

Looks good to me. Ready to merge.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

ValidateResume.js changes resume schema definitions and validation middleware. The changes remove the Mongoose import while retaining references to it, duplicate save-schema fields, and define duplicate analyze validators with different parsing behavior.

Changes

Resume validation

Layer / File(s) Summary
Resume schema definitions
backend/Input_validators/ValidateResume.js
saveResumeSchema adds explicit type messages but duplicates title, latexCode, and resumeId. ObjectId checks still reference the removed mongoose identifier.
Validation middleware flow
backend/Input_validators/ValidateResume.js
Compile validation uses shared validate middleware. Two validateAnalyzeResume declarations remain, including an asynchronous parser that cleans up uploaded files on validation errors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: type:security

Suggested reviewers: dev1822, ionfwsrijan, karanunique

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The changes introduce unrelated defects, including undefined mongoose references, duplicate schema fields, and duplicate analyze validation implementations. Remove unrelated changes and restore the mongoose import or replace its references; remove duplicate fields and the duplicate validateAnalyzeResume implementation.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the compileResume validation fix described by the pull request and linked issue.
Linked Issues check ✅ Passed The changes validate missing or non-string req.body.code values before compilation and support a 400 response for issue #1622.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.6)
backend/Input_validators/ValidateResume.js

File contains syntax errors that prevent linting: Line 124: expected } but instead the file ends


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/Input_validators/ValidateResume.js`:
- Around line 56-59: Update the validation failure path around
analyzeResumeSchema.safeParse to delete any uploaded temporary file before
returning handleValidationError. Reuse the existing upload cleanup mechanism, if
available, and ensure cleanup runs for rejected requests that include a file
without changing the validation response.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6d4c3b79-4248-4885-8cde-bb421a14722b

📥 Commits

Reviewing files that changed from the base of the PR and between ca675c8 and 6dd2aaf.

📒 Files selected for processing (1)
  • backend/Input_validators/ValidateResume.js

Comment on lines +10 to +13
.string({
required_error: "LaTeX code is required",
invalid_type_error: "LaTeX code must be a 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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Zod 4 migration guide required_error invalid_type_error unified error parameter

💡 Result:

In Zod 4, error customization has been standardized under a single, unified error parameter, replacing the previously fragmented API [1][2]. Key migration points: 1. Unified Error Parameter: The legacy message parameter (often used for simple string overrides) has been deprecated in favor of the error parameter [1][2]. This new parameter accepts an error map function, allowing for consistent error handling across the library [3][4]. 2. Deprecation of Fragmented APIs: Previous approaches to customizing errors—such as passing separate error messages or using inconsistent configuration objects—have been cleaned up to improve cohesion [1][2]. 3. Error Maps: Error customization is now centrally managed through error maps. These functions receive an issue object (iss), which is a discriminated union of all possible issue types, allowing you to handle specific codes like invalid_type or too_small precisely [3][4]. 4. Migration Assistance: An unofficial community-maintained codemod (zod-v3-to-v4) is available to automate many of these breaking changes [1]. Official documentation suggests reading the Zod 4 migration guide thoroughly as it lists changes in order of impact [1][2]. To upgrade to Zod 4, install the latest version: npm install zod@^4.0.0 [5][6] For detailed customization examples, including per-parse and global configurations using the unified error approach, refer to the Zod 4 error customization documentation [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- candidate files ---'
git ls-files | grep -E '(^|/)(ValidateResume\.js|package\.json|package-lock\.json|yarn\.lock|pnpm-lock\.yaml)$' || true

printf '%s\n' '--- validator source ---'
file=$(git ls-files | grep 'backend/Input_validators/ValidateResume\.js$' | head -n 1)
if [ -n "${file:-}" ]; then
  cat -n "$file"
fi

printf '%s\n' '--- Zod dependency declarations ---'
while IFS= read -r f; do
  case "$f" in
    *package.json|*package-lock.json|*yarn.lock|*pnpm-lock.yaml)
      grep -nE '"zod"|(^|[[:space:]])zod([@[:space:]:]|$)' "$f" || true
      ;;
  esac
done < <(git ls-files | grep -E '(^|/)(package\.json|package-lock\.json|yarn\.lock|pnpm-lock\.yaml)$')

printf '%s\n' '--- validator usages ---'
rg -n --glob '!node_modules' 'ValidateResume|resumeSchema|latexCode|title: z\.string' backend . || true

Repository: Canopus-Labs/PrepPilot

Length of output: 3460


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
import json
from pathlib import Path

for name in ["package.json", "backend/package.json", "frontend/package.json"]:
    p = Path(name)
    if not p.exists():
        continue
    data = json.loads(p.read_text())
    deps = {}
    deps.update(data.get("dependencies", {}))
    deps.update(data.get("devDependencies", {}))
    print(f"{name}: zod declaration = {deps.get('zod', '<absent>')}")

for name in ["package-lock.json", "backend/package-lock.json", "frontend/package-lock.json"]:
    p = Path(name)
    if not p.exists():
        continue
    data = json.loads(p.read_text())
    versions = set()
    packages = data.get("packages", {})
    for key, value in packages.items():
        if key.endswith("/node_modules/zod") or key == "node_modules/zod":
            if "version" in value:
                versions.add(value["version"])
    if not versions:
        root = data.get("dependencies", {}).get("zod", {})
        if root.get("version"):
            versions.add(root["version"])
    print(f"{name}: locked zod versions = {sorted(versions) or '<absent>'}")
PY

printf '%s\n' '--- all Zod declarations/usages ---'
rg -n --glob '!node_modules' --glob '*package*.json' --glob '*lock*' '"zod"|node_modules/zod' . || true

Repository: Canopus-Labs/PrepPilot

Length of output: 662


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- validation error handling ---'
file=$(git ls-files | grep 'backend/Input_validators/ValidateQuestions\.js$' | head -n 1)
if [ -n "${file:-}" ]; then
  cat -n "$file"
fi

printf '%s\n' '--- validation message consumers and tests ---'
rg -n --glob '!node_modules' 'LaTeX code is required|LaTeX code must be a string|Title is required|Title must be a string|required_error|invalid_type_error|validateCompileResume|validateSaveResume|handleValidationError' backend . || true

printf '%s\n' '--- Zod lockfile package metadata ---'
python3 - <<'PY'
import json
from pathlib import Path
p = Path("backend/package-lock.json")
data = json.loads(p.read_text())
for key, value in data.get("packages", {}).items():
    if key.endswith("/node_modules/zod"):
        print(key, value)
PY

Repository: Canopus-Labs/PrepPilot

Length of output: 16477


🌐 Web query:

site:zod.dev/v4/changelog required_error invalid_type_error removed Zod 4

💡 Result:

In Zod 4, the previously used invalid_type_error and required_error parameters have been removed to standardize error customization [1]. These parameters were removed because they were inconsistent, conflicted with errorMap usage, and did not align with Zod's internal issue codes (as there is no native 'required' issue code) [1]. To replace this functionality, Zod 4 introduces a unified error parameter that accepts a function [1]. This function receives the ZodIssue object and allows for logic-based error message customization [1]. For example, to replicate the behavior of a required field error: z.string({ error: (issue) => issue.input === undefined? "This field is required": "Not a string" }); By returning undefined from this function, you can also signal Zod to fall back to the next error map in the chain [1].

Citations:


Replace the removed Zod 4 error options.

Use error customization for code, title, and latexCode. Zod 4 removed required_error and invalid_type_error, so these fields currently use default messages for missing and non-string inputs.

📍 Affects 1 file
  • backend/Input_validators/ValidateResume.js#L10-L13 (this comment)
  • backend/Input_validators/ValidateResume.js#L27-L34

Comment thread backend/Input_validators/ValidateResume.js
@KaranUnique

Copy link
Copy Markdown
Contributor

@suhaniiz Address the coderabbit suggestions and resolve the merge conflicts

@suhaniiz

suhaniiz commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

@KaranUnique , resolved

@github-actions github-actions Bot added merge ready PR is mergeable and has no conflicts merge conflicts PR has merge conflicts labels Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

@suhaniiz, please resolve the commit so that it will be merged soon ......

@github-actions github-actions Bot removed the merge ready PR is mergeable and has no conflicts label Aug 9, 2026

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
backend/Input_validators/ValidateResume.js (3)

61-68: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Remove the conflicting middleware implementations. The module contains unresolved alternative implementations for both compile and analyze validation. These declarations make ValidateResume.js fail to parse, so no exported validator can load.

  • backend/Input_validators/ValidateResume.js#L61-L68: retain one validateCompileResume declaration that validates req.body || {}.
  • backend/Input_validators/ValidateResume.js#L72-L104: retain one complete validateAnalyzeResume declaration and keep cleanup for rejected uploaded files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Input_validators/ValidateResume.js` around lines 61 - 68, In
backend/Input_validators/ValidateResume.js lines 61-68, remove the duplicate
validateCompileResume declaration and retain one implementation that validates
req.body || {}. In lines 72-104, remove the conflicting validateAnalyzeResume
implementation and retain one complete declaration, preserving cleanup of
rejected uploaded files.

46-56: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore the mongoose binding before ObjectId validation.

mongoose.isValidObjectId has no imported binding. A save request with a non-empty resumeId, or any delete request with an id, can throw instead of returning a validation response. Restore the import or replace both calls with an imported ObjectId validator.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Input_validators/ValidateResume.js` around lines 46 - 56, Restore the
mongoose binding in ValidateResume.js, or use an imported ObjectId validator, so
both resumeId validation in the resume schema and id validation in
deleteResumeSchema can call isValidObjectId without a ReferenceError. Preserve
the existing optional resumeId behavior and validation messages.

31-49: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the duplicate schema keys.

The final declarations at Lines 44-49 overwrite the earlier title, latexCode, and resumeId definitions. Keep one definition for each field so the active validation contract is explicit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Input_validators/ValidateResume.js` around lines 31 - 49, Remove the
duplicate title, latexCode, and resumeId declarations from the schema, keeping
one definition for each field. Preserve the earlier definitions with required
and invalid-type messages, and retain the mongoose.isValidObjectId refinement on
resumeId by incorporating it into that single definition.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@backend/Input_validators/ValidateResume.js`:
- Around line 61-68: In backend/Input_validators/ValidateResume.js lines 61-68,
remove the duplicate validateCompileResume declaration and retain one
implementation that validates req.body || {}. In lines 72-104, remove the
conflicting validateAnalyzeResume implementation and retain one complete
declaration, preserving cleanup of rejected uploaded files.
- Around line 46-56: Restore the mongoose binding in ValidateResume.js, or use
an imported ObjectId validator, so both resumeId validation in the resume schema
and id validation in deleteResumeSchema can call isValidObjectId without a
ReferenceError. Preserve the existing optional resumeId behavior and validation
messages.
- Around line 31-49: Remove the duplicate title, latexCode, and resumeId
declarations from the schema, keeping one definition for each field. Preserve
the earlier definitions with required and invalid-type messages, and retain the
mongoose.isValidObjectId refinement on resumeId by incorporating it into that
single definition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 63abc797-04d9-46a7-bd40-48106dda5e51

📥 Commits

Reviewing files that changed from the base of the PR and between 6dd2aaf and 209a0c4.

📒 Files selected for processing (1)
  • backend/Input_validators/ValidateResume.js

@suhaniiz

Copy link
Copy Markdown
Contributor Author

@KaranUnique , conflicts resolved

@github-actions github-actions Bot added merge ready PR is mergeable and has no conflicts and removed merge conflicts PR has merge conflicts labels Aug 11, 2026
@github-actions github-actions Bot added the merge conflicts PR has merge conflicts label Aug 11, 2026
@github-actions

Copy link
Copy Markdown

@suhaniiz, please resolve the commit so that it will be merged soon ......

@github-actions github-actions Bot removed the merge ready PR is mergeable and has no conflicts label Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge conflicts PR has merge conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Server returns 500 Internal Server Error when req.body.code is missing or undefined

2 participants