fix: nest role type in update_opportunity_roles payload (unbreak set-role) - #15
Merged
Conversation
The endpoint expects each role entry's type nested under a 'role' array:
{contact_id, is_primary, role: [{opportunity_contact_role_type_id, is_primary}]}.
The client sent opportunity_contact_role_type_id flat on the entry with no
'role' key, so Apollo ran .map on nil and 422'd with
"undefined method 'map' for nil" — making 'deals set-role' fail every time.
update_opportunity_roles now reshapes the flat RoleAssignment entries into
the nested wire format (role type omitted from the nested object when absent).
Public RoleAssignment interface is unchanged. Live-verified end-to-end:
linked a contact + flipped role type, both persisted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| # into the wire format the server actually accepts. | ||
| wire_roles: list[dict] = [] | ||
| for entry in roles: | ||
| is_primary = bool(entry.get("is_primary")) |
There was a problem hiding this comment.
Improvement: is_primary = bool(entry.get("is_primary")) will treat any truthy non-bool (e.g. the string 'false') as True, and it also forces an omitted value to False.
Fix: consider
is_primary = entry.get("is_primary", False)(and optionallyisinstance(is_primary, bool)/ raise) so you don’t accidentally flip primaries due to Python truthiness.
There was a problem hiding this comment.
👍 Update looks good — switching to entry.get("is_primary", False) avoids the truthiness pitfall I mentioned. Feel free to mark this thread resolved.
…l() coercion
Per peqy: bool(entry.get('is_primary')) would coerce a stray truthy non-bool
(e.g. the string 'false') to True. RoleAssignment types is_primary as bool,
so default to False when omitted and pass the value through unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 9, 2026
Merged
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.
The bug
update_opportunity_roles(backingdeals set-role) sent the role type flat on each entry:{"opportunity_id": "…", "roles": [{"contact_id": "…", "opportunity_contact_role_type_id": "…", "is_primary": true}]}Apollo 422'd every call with
undefined method 'map' for nil— its handler calls.mapon each entry'srolefield, which was absent. The command never worked against the live API (it passed only because tests mock the client).Root cause
Captured the app UI's own
update_rolescall: each entry nests the role type under arolearray:{"contact_id": "…", "is_primary": true, "role": [{"opportunity_contact_role_type_id": "…", "is_primary": true}]}Fix
update_opportunity_rolesnow reshapes the flatRoleAssignmententries into that nested wire format (role type omitted from the nested object when the caller didn't supply one). The publicRoleAssignmentinterface is unchanged — callers still pass flat entries.Testing
test_update_opportunity_rolesto assert the nested body (both with- and without-role-type entries).num_contacts=1, correct role type on GET).Note: no CLI change needed (
deals set-rolealready sends flat entries). No version bump (left for release time).🤖 Generated with Claude Code