Skip to content

fix(management): reject non-object custom-model bodies - #2408

Merged
Ingwannu merged 1 commit into
lidge-jun:devfrom
luvs01:fix/custom-model-json-body
Aug 23, 2026
Merged

fix(management): reject non-object custom-model bodies#2408
Ingwannu merged 1 commit into
lidge-jun:devfrom
luvs01:fix/custom-model-json-body

Conversation

@luvs01

@luvs01 luvs01 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Require custom-model POST and PUT JSON bodies to be plain records before field access.
  • Return the existing 400 { "error": "invalid JSON body" } envelope for null, arrays, and primitive JSON values.
  • Preserve malformed JSON, oversized-body, and valid-object behavior while preventing rejected bodies from reaching persistence.

Verification

  • Bun 1.4 focused regression: bun test --isolate tests/catalog-input-modality-enum.test.ts — 31 passed, 0 failed, 107 assertions.
  • bun run typecheck — passed.
  • bun run privacy:scan — passed.
  • git diff --check — passed.
  • Independent exact-diff review — no actionable findings.
  • Exact head be305244762bca7078a26adaf474933a37de2a6e, based directly on dev at 4f41a8e936141af7ee828e335da314b9dc1ef761.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. This adds defensive input validation without changing configuration or public API shape.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. This changes no credential or authorization boundary and prevents invalid bodies from reaching persistence.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes
    • Custom model creation and updates now reject invalid JSON bodies, including null, arrays, and strings.
    • Invalid requests return a clear HTTP 400 error without modifying existing data.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 22, 2026
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f830505d-02c6-4025-9e31-2dda4340ca25

📥 Commits

Reviewing files that changed from the base of the PR and between 4f41a8e and be30524.

📒 Files selected for processing (2)
  • src/server/management/model-routes.ts
  • tests/catalog-input-modality-enum.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

Custom-model POST and PUT routes now reject non-object JSON bodies with HTTP 400 before field access. Tests verify the error payload and confirm that persistence and existing fixtures remain unchanged.

Changes

Custom-model body validation

Layer / File(s) Summary
Validate custom-model request bodies
src/server/management/model-routes.ts
The POST handler at lines 397–400 and the PUT handler at lines 446–449 validate parsed bodies as plain objects. Invalid shapes return { error: "invalid JSON body" } with HTTP 400.
Verify rejection and state preservation
tests/catalog-input-modality-enum.test.ts
Tests cover null, arrays, and strings for POST and PUT. They verify the 400 response, error payload, no persistence, and unchanged fixtures.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to be305

This localized change rejects invalid custom-model request bodies while preserving existing valid and error behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: ingwannu, lidge-jun, robinbially

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 and concisely describes the main change: rejecting non-object custom-model request bodies.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 54 / 80

설명: 이 PR은 사용자 정의 모델을 만드는 POST 와 고치는 PUT 에서, JSON 본문이 평범한 객체 기록이 아니면 바로 400 으로 거절한다. 지금 CURRENT dev HEAD 는 4f41a8e93 이다. 이번 시간에 origin/dev 는 46d4150 에서 한 커밋이 와서 여기까지 왔다. 착지는 2396 사용량 CLI 오늘 비용이다. package.json 은 2.27.0 이다. src/config.ts 는 3975줄이다. src/runtime 폴더는 지금 HEAD 에 없다. 지금 HEAD 의 src/server/management/model-routes.ts 396줄 POST 와 441줄 PUT 은 JSON 을 읽은 뒤 본문 모양을 안 본다. 같은 파일 147줄은 이미 isPlainRecord 를 shared 에서 가져온다. shared.ts 60줄은 객체이고 null 이 아니고 배열이 아닌 기록만 참이다. 본문이 null 이면 body.provider 나 body.modelId 를 읽는 순간 서버가 터진다. 배열이나 글자면 POST 는 provider and modelId are required 로 400 이 나고, PUT 은 필드가 없다고 보고 저장 길로 갈 수 있다. 깨진 JSON 과 큰 본문은 이미 400 invalid JSON body 다. 이 PR 은 두 길에 isPlainRecord 가드를 넣고 같은 400 봉투를 쓴다. 테스트는 null, 배열, 글자 본문이 persistCalls 를 0 으로 두고 customModels 를 안 바꾸는 것을 잠근다. 작성자 로컬은 catalog-input-modality-enum 31개, typecheck, privacy:scan 통과라고 적었다. 드래프트가 아니다. bug 와 review-ready 라벨이 있다. 체크리스트 네 칸이 채워져 있다. 작성자는 luvs01 이다. 베이스는 지금 HEAD 와 같다. Closes 가 없다. GitHub 위생/타깃/CodeRabbit 만 초록이다. Cross-platform CI 는 아직 안 보인다. 사용자 길이로는 관리 API 가 잘못된 본문으로 터지거나 잘못된 400 을 내는 구멍이라서 54. 카탈로그 팁은 Ox Alpha x-preview-f-free + deepseek-v4-flash-vision-exp. Cursor 정적 카탈로그는 opus-4-8-fast / opus-5-fast. 2334 CursorCredentialRouter 는 여전히 src/providers/cursor-pool.ts 모듈+테스트만 있고 어댑터에 연결되지 않았다. 2332 H2 는 discovery 전용. 2320 overflow + 2342 는 이미 dev. 2188 사이드카는 이미 dev. 2382 데스크톱 앱 재시작은 이미 dev. 2292 는 아직 연다.

src/server/management/model-routes.ts 라인 396 - 지금 HEAD POST 는 JSON 을 읽은 뒤 isPlainRecord 를 안 본다. null 이면 body.provider 에서 터진다
src/server/management/model-routes.ts 라인 441 - PUT 도 같다. null 이면 body.modelId 에서 터진다. 배열은 필드가 없다고 보고 저장 길로 갈 수 있다
src/server/management/model-routes.ts 라인 147 - 같은 파일이 이미 isPlainRecord 를 가져온다. PR 은 그걸 두 길에 쓴다
src/server/management/shared.ts 라인 60 - isPlainRecord 는 객체이고 null 이 아니고 배열이 아닌 기록만 참이다
tests/catalog-input-modality-enum.test.ts - null, 배열, 글자 본문이 400 invalid JSON body 이고 persistCalls 가 0 인지 잠근다
GitHub CI - Cross-platform CI 가 아직 안 보인다. 작성자 로컬은 31개 통과

메인테이너의 판단이 필요한 지점

  • GitHub 시험이 아직 안 뜬 채로 머지할지. 작성자 로컬은 이미 통과라고 적었다
  • 다른 관리 POST 도 같은 가드가 필요한지. 이 PR 은 custom-models 두 길만 고친다
  • 이 구멍을 이슈로 남길지. 본문에 Closes 가 없다

너의 추천
GitHub 시험이 초록이면 머지한다. 가드를 더 넓히지 말 것. 깨진 JSON 과 큰 본문 길은 이미 있으니 손대지 않는다. types.ts/config.ts 스플릿과 겹치면 닫고 리베이스하지 않는데, 지금은 그 정도 아님. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.

이 댓글은 grok-bot이 작성했습니다

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Verified exact head be30524. The change is narrowly scoped to rejecting non-object JSON bodies on custom-model POST/PUT before field access or persistence. Focused coverage locks null, array, and primitive inputs; the full cross-platform CI, final aggregate gate, hygiene, and CodeRabbit checks are green. Approved for dev.

@Ingwannu
Ingwannu merged commit 03c7239 into lidge-jun:dev Aug 23, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants