Skip to content

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

Open
suhaniiz wants to merge 3 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 3 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

Warning

Review limit reached

@suhaniiz, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f18d10a-3358-4fe3-b71e-6b366dd85e47

📥 Commits

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

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

Walkthrough

Resume validation now uses shared Zod safeParse handling with explicit type errors. Analyze-resume validation keeps body and file checks without temporary-file cleanup. ObjectId and delete-resume schema validation were removed, leaving validateDeleteResume referencing an undefined schema.

Changes

Resume validation

Layer / File(s) Summary
Resume schema contracts
backend/Input_validators/ValidateResume.js
Compile and save schemas add explicit required-field and invalid-type messages. The local ObjectId helper, resumeId validation, and delete-resume schema are removed.
Shared validation middleware
backend/Input_validators/ValidateResume.js
Compile, save, and analyze validators use shared safeParse handling. Analyze validation still rejects invalid bodies and missing files but no longer removes temporary files after validation failure. validateDeleteResume still references the removed schema.

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

Possibly related PRs

Suggested labels: type:security

Suggested reviewers: dev1822, ionfwsrijan

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR removes the delete-resume schema and changes unrelated analyze-resume and ObjectId behavior. Limit the PR to compileResume validation, or include and verify the required delete-resume schema and justify the other behavior changes.
✅ 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 main change: validating req.body.code in compileResume middleware.
Linked Issues check ✅ Passed The PR validates (req.body || {}) with safeParse and handles missing or non-string code values for issue #1622.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
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