Nobody has started this yet — be first.
Business impact
Anyone can post a comment with no actual content -- an empty string, or a string of only spaces/tabs/newlines that renders as a blank line in any UI. On a public blog that's a moderation and trust problem: blank comments clutter every post's comment thread, make it harder for real readers to follow a discussion, and are exactly the shape of noise automated spam/abuse tools send first to probe whether validation exists at all.
Problem
createCommentSchema.content is declared as z.string().trim().min(0, 'Content must not be empty'). .trim() strips leading/trailing whitespace, but .min(0, ...) accepts a string of length zero -- so both "" and " " (which trims to "") pass validation and the comment is created.
Current behavior
POST /posts/:id/comments with content: "" or content: " " returns 201 Created and stores a blank comment, instead of the 400 VALIDATION_ERROR the schema's own error message claims it enforces.
Expected behavior
A comment whose content is empty, or entirely whitespace, is rejected with 400 VALIDATION_ERROR, matching the "must not be empty" message the schema already declares (and matching how createPostSchema.title / createPostSchema.content already enforce the same rule with .min(1, ...)).
Steps to reproduce
cd nodejs/blog_api npm test -- tests/comments.test.js
curl -s -X POST http://localhost:3000/posts/1/comments
-H "Authorization: Bearer <token>" -H "Content-Type: application/json"
-d '{"content": " "}'
Why this matters
.min(0, ...) and .min(1, ...) are one character apart and both "look" like a length check at a glance -- a classic boundary-value slip, made worse here because the message string attached to the rule ('Content must not be empty') still reads as if the check works, so a quick read of the schema doesn't reveal the bug; you have to notice the argument is 0, not 1.
Suggested approach
Compare createCommentSchema.content in src/validation/schemas.js against createPostSchema.content a few lines above, which enforces the identical "non-empty after trim" rule correctly.
Acceptance criteria
Verification
node_modules/.bin/jest --config practice-tickets/jest.config.js practice-tickets/tests/ticket02_empty_comment_content_accepted.test.js --verbose
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
$git checkout -b fix/empty-comment-content-acceptedFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/empty-comment-content-acceptedSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign indocker compose down -vTo run locally without Docker, you need a local PostgreSQL instance:
npm install
cp .env.example .env # edit DATABASE_URL, JWT_SECRET, etc.
npm run prisma:migrate:dev # applies migrations to your local Postgres
npm run dev # starts with --watch on http://localhost:3000
Run the project's own test suite (real Postgres, not mocks -- point DATABASE_URL at a disposable database first):
npm test
Work the tickets in practice-tickets/ (ticket01 through ticket07); each has its own dedicated Jest test under practice-tickets/tests/, run via a separate Jest config (practice-tickets/jest.config.js) so plain npm test never picks them up:
docker compose up -d postgres # if it isn't already running
npm run prisma:migrate
./practice-tickets/run_tickets.sh # all 7, clean pass/fail summary
node_modules/.bin/jest --config practice-tickets/jest.config.js \
practice-tickets/tests/ticket01_pagination_skip_off_by_one.test.js --verbose # a single ticket
Level 1
Fix a bug
Read existing behaviour, correct it.