Skip to content

fix: serialize pydantic request bodies before passing to httpx json= - #2

Open
MCPVOT wants to merge 1 commit into
GoHighLevel:mainfrom
MCPVOT:fix/serialize-pydantic-bodies
Open

fix: serialize pydantic request bodies before passing to httpx json=#2
MCPVOT wants to merge 1 commit into
GoHighLevel:mainfrom
MCPVOT:fix/serialize-pydantic-bodies

Conversation

@MCPVOT

Copy link
Copy Markdown

Problem

Generated service methods pass typed request DTOs (pydantic BaseModel) straight to httpx json=. httpx uses plain json.dumps (no default=), which cannot serialize BaseModel — every typed POST/PUT method (create_contact, update_contact, upsert_contact, create_note, add_tags, ...) crashes with TypeError before reaching the network. Only plain-dict bodies work.

Fix

  • New serialize_payload() in src/highlevel/utils/request_utils.py: model_dump(exclude_none=True) for BaseModel, recursive for dict/list, passthrough for primitives, None stays None.
  • Wrapped all 291 call sites across 42 service files; import updated identically everywhere.

Verification

  • py_compile clean on all 43 modified files
  • serialize_payload(CreateContactDtoV3(locationId, firstName, email, customFields=[{key: event_id, fieldValue: ...}])) → JSON-serializable dict with exact customFields shape preserved
  • Edge cases pass: None → None, dict → passthrough, list of models → list of dicts
  • No behavior change for existing dict-based callers (passthrough)

Impact

Unblocks every typed-body method in the SDK (the most common usage per the README). ~10 lines of real logic in one place.

Generated service methods pass typed request DTOs (pydantic BaseModel) straight
to httpx json=, which cannot serialize them (TypeError: not JSON serializable)
— every typed POST/PUT method crashed before reaching the network. Only plain
dicts worked.
Add serialize_payload() to request_utils (model_dump(exclude_none=True), with
recursive handling for dicts/lists), and wrap the 291 call sites across 42
service files. Dicts and primitives pass through unchanged; None stays None.
Verified: py_compile clean on all files; serialize_payload(CreateContactDtoV3)
produces a JSON-serializable dict with the exact proven customFields shape
({key, fieldValue}); edge cases (None, dict, nested list) pass.
@MCPVOT
MCPVOT requested a review from a teamAugust 9, 2026 18:31

@orca-security-usorca-security-usBot 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.

Orca Security Scan Summary

StatusCheckIssues by priority
Passed PassedInfrastructure as Codehigh 0 medium 0 low 0 info 0View in Orca
Passed PassedSASThigh 0 medium 0 low 0 info 0View in Orca
Passed PassedSecretshigh 0 medium 0 low 0 info 0View in Orca
Passed PassedVulnerabilitieshigh 0 medium 0 low 0 info 0View in Orca

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@MCPVOT