Repository navigation
[DONE] 커뮤니티 API 가 본문이 null 인 요청에 500 대신 400 과 까닭을 돌려준다 - #147
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Yb77jeCcRxZfC8EHziz4Gg
null parses as JSON, so it passed every route's catch and threw on the first field read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Yb77jeCcRxZfC8EHziz4Gg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Yb77jeCcRxZfC8EHziz4Gg
patternflow-bot
marked this pull request as ready for review
October 22, 2026 01:12
This was referenced Oct 22, 2026
engmung
pushed a commit
to engmung/Patternflow
that referenced
this pull request
Oct 22, 2026
engmung
pushed a commit
to engmung/Patternflow
that referenced
this pull request
Oct 22, 2026
Patternflow-lab#108 Patternflow-lab#109 Patternflow-lab#110 Patternflow-lab#111 Patternflow-lab#112 Patternflow-lab#113 Patternflow-lab#114 Patternflow-lab#115 Patternflow-lab#116 Patternflow-lab#117 Patternflow-lab#118 Patternflow-lab#119 Patternflow-lab#120 Patternflow-lab#121 Patternflow-lab#122 Patternflow-lab#123 Patternflow-lab#124 Patternflow-lab#125 Patternflow-lab#126 Patternflow-lab#127 Patternflow-lab#128 Patternflow-lab#130 Patternflow-lab#131 Patternflow-lab#132 Patternflow-lab#133 Patternflow-lab#134 Patternflow-lab#135 Patternflow-lab#136 Patternflow-lab#137 Patternflow-lab#138 Patternflow-lab#139 Patternflow-lab#140 Patternflow-lab#141 Patternflow-lab#142 Patternflow-lab#144 Patternflow-lab#145 Patternflow-lab#146 Patternflow-lab#147 Patternflow-lab#148 Patternflow-lab#149 Patternflow-lab#150 Patternflow-lab#151 Patternflow-lab#152 Patternflow-lab#153 Patternflow-lab#154 Patternflow-lab#155 Patternflow-lab#156 Patternflow-lab#157 Patternflow-lab#158 Patternflow-lab#159
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
lsh / https://claude.ai/code/session_01Yb77jeCcRxZfC8EHziz4Gg
커뮤니티 쓰기 라우트 22곳은 본문
null을 받으면 첫 칸을 읽다 TypeError 로 죽었고, Next.js 는 빈 500 을 CORS 머리 없이 돌려줬어요. 머지하면 21개 파일이readJsonObject하나로 본문을 읽고, 객체가 아닌 본문에{"error":"Expected a JSON object."}와 400 을 돌려줘요. 다른 출처의 Pattern Lab 도 그 까닭을 읽을 수 있어요.좋아지는 것: 없음
할 일
3 은 바퀴 4547 이 했고, 4 를 맡아요lib/community/jsonBody.ts와 시험, 라우트 21곳null보내 보기한 일
web/src/lib/community/jsonBody.ts의readJsonObject(request)는 본문을 읽어 객체면 그대로, 아니면 400 응답을 돌려줘요. JSON 이 아니면 지금처럼 「Invalid JSON body.」,null이나 배열, 수, 글자면 「Expected a JSON object.」예요. 라우트는 두 줄로 불러요.try/catch와as Record<string, unknown>을 이 두 줄로 바꾼 곳은 21개 파일이에요.atlas(POST, DELETE),builds,comments/[id],decks,decks/[id],featured,patterns,patterns/[id], 그 아래comments·header·performance,ports/[id],posts,posts/[id], 그 아래comments·pin,presence,reports,reports/[id],territories,territories/[code]이에요. 400 은 라우트 안에서 돌려주니 다른 400 처럼withCors를 지나요.시험은 둘이에요.
jsonBody.test.ts는 객체, 빈 객체, 객체가 아닌 JSON 여섯 가지, 본문 없음, 빈 본문, 끊긴 객체를 봐요.app/api/community/nullBody.test.ts는decks/[id]/route.test.ts처럼 제 데이터베이스에 관리자 하나와 패턴, 덱, 댓글, 포트, 영역, 글, 신고를 넣고 22곳에 로그인과 Lab 의 Origin 을 달아null을 보내요. 400, 그 JSON,Access-Control-Allow-Origin셋을 봐요.증거
고치기 전
npx vitest run src/app/api/community/nullBody.test.ts. 22곳이 다 같은 꼴로 죽어요.고친 뒤.
dev(
7a58ce2)와 이 브랜치를 각각npm run build하고next start로 3101, 3100 에 띄웠어요. 가입해 받은 쿠키와Origin: https://lab.patternflow.test를 달고POST /api/community/patterns에 본문 셋을 보냈어요.web/에서 다섯 검사의 끝줄이에요.check:ci의links-absolute와roadmap은gh로그인이 없는 컨테이너라skipped예요.npm run check:voice는 「read: 272 added lines in 24 files · nothing found」예요. 화면을 바꾸지 않아서 사진은 없어요.실행법
cd web npx vitest run src/lib/community/jsonBody.test.ts src/app/api/community/nullBody.test.ts가정
[]가 패턴 올리기에서 「Title is required」였어요. 쪽에서JSON.stringify에 객체 꼴이 아닌 값을 넘기는 일곱 곳(AtlasClient.tsx:409,ModerateVisibility.tsx:45,TerritoryEditor.tsx:114,PublishModal.tsx:185,AddHeaderModal.tsx:90,PresenceLayer.tsx:137,DeckDetailClient.tsx:145)을 따라가 보니 다 객체를 보내요.BUILD_ENABLED=1을 켜서, 그 아홉 파일까지 22곳 다 죽는 걸 봤어요.territories/[code]/pin/route.ts:82는 표대로 두었어요. 본문이 없어도 되는 라우트라null이면 메모 없이 핀을 꽂아요.comments/[id]PATCH 는 본문을 읽기 전에?on=pattern|post를 봐서, 시험 주소에?on=pattern을 붙였어요.builds/route.ts:113의const item = entry as Record<string, unknown>은{"format":"pfm","patterns":[null]}에서item.code를 읽다 같은 TypeError 가 날 거예요(코드로 봤어요). 본문null이 아니라 배열 안의null이라 고치지 않았어요.Changelog
Web
nullbody with a 400.nullparses as JSON, so it got past every route'scatchand threw on the first field read, and 22 handlers answered an empty 500 with no CORS headers. They now read the body through one helper that answers{"error":"Expected a JSON object."}.경험
언제: 바퀴에서 dev 를 따로 빌드해 이 브랜치와 나란히 띄울 때
교훈: dev 워크트리의
web/node_modules는 심볼릭 링크 말고cp -al로 하드 링크 복사를 한다근거: #147 에서
../wt-dev/web/node_modules를 심볼릭 링크로 두자 Turbopack 이 「Symlink node_modules could not be resolved: the symlink target leaves the filesystem root」로 빌드를 멈췄고,cp -al은 0.5초에 끝났고 그 뒤 빌드는 「Compiled successfully in 13.7s」로 통과했어요바퀴
바퀴 48 · 후보 4 「커뮤니티 API 가 본문이
null인 요청에 500 대신 400 과 까닭을 돌려준다」다음 바퀴
lib/pattern/harness.ts:437이 덧댄return이 끊긴 호출 안으로 들어가 「Unexpected token 'return'」이 떠요.http://를 붙여 넣어도 「Send over Wi-Fi」 링크가 그 보드로 간다」 —lib/community/deviceHost.ts:65가 빈 칸에서http:///patterns?src=…를 만들어요.https://claude.ai/code/session_01Yb77jeCcRxZfC8EHziz4Gg
Generated by Claude Code