Skip to content

fix: Align connector entity client with API schema#43

Open
dmcnaught wants to merge 1 commit intopenguintechinc:mainfrom
dmcnaught:fix/connector-entity-update-validation
Open

fix: Align connector entity client with API schema#43
dmcnaught wants to merge 1 commit intopenguintechinc:mainfrom
dmcnaught:fix/connector-entity-update-validation

Conversation

@dmcnaught
Copy link

@dmcnaught dmcnaught commented Feb 5, 2026

Summary

  • Fix 400 Bad Request errors when connector updates AWS resources (VPCs, EC2, RDS, ElastiCache, SQS, Lambda)
  • Remove organization_id and owner_identity_id from update_entity as they're not valid update fields
  • Add sub_type to both create_entity and update_entity to properly support entity sub-types

Problem

The connector's update_entity method was sending fields that the API's UpdateEntityRequest schema doesn't accept. Since UpdateEntityRequest uses extra='forbid' (from RequestModel), any extra fields cause immediate validation failures:

  • organization_id: Not updatable after entity creation - entities are bound to their organization
  • owner_identity_id: Not defined in the UpdateEntityRequest schema

This caused all AWS resource syncs (except S3 buckets) to fail with 400 errors when updating existing entities.

Root Cause

# API's UpdateEntityRequest (extra='forbid' from RequestModel base class)
class UpdateEntityRequest(RequestModel):
    name: Optional[str] = None
    description: Optional[str] = None
    entity_type: Optional[str] = None
    sub_type: Optional[str] = None      # Supported but connector wasn't sending
    parent_id: Optional[int] = None
    attributes: Optional[dict] = None
    tags: Optional[list[str]] = None
    default_metadata: Optional[dict] = None
    is_active: Optional[bool] = None
    # organization_id NOT here - not updatable
    # owner_identity_id NOT here - not a valid field

Test plan

  • Deploy connector with this fix
  • Trigger AWS sync
  • Verify VPCs, EC2 instances, RDS, ElastiCache, SQS queues, and Lambda functions are discovered and updated without 400 errors
  • Verify S3 buckets continue to work (they were unaffected)
  • Verify sub_type is properly set for entities that use it (RDS, ElastiCache, SQS, Lambda)

Summary by Sourcery

Align connector entity create and update payloads with the API's UpdateEntityRequest schema to prevent validation errors when syncing entities.

Bug Fixes:

  • Stop sending non-updatable fields organization_id and owner_identity_id in entity update requests to prevent 400 Bad Request errors.
  • Include sub_type in entity create and update requests so entity sub-types are correctly persisted.

Enhancements:

  • Add logging context for sub_type when creating and updating entities to improve observability.

The update_entity method was sending fields that aren't accepted by
the API's UpdateEntityRequest schema (which uses extra='forbid'):
- organization_id: Not updatable after creation
- owner_identity_id: Not a valid update field

This caused 400 Bad Request errors when the connector tried to update
discovered AWS resources (VPCs, EC2, RDS, ElastiCache, SQS, Lambda).
Only S3 buckets worked because they didn't trigger updates.

Changes:
- Remove organization_id from update_entity (not changeable)
- Remove owner_identity_id from update_entity (not in schema)
- Add sub_type to both create_entity and update_entity (supported by API)
- Add documentation explaining the update constraints
- Add sub_type to logging for better observability
@sourcery-ai
Copy link

sourcery-ai bot commented Feb 5, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Aligns the connector's entity creation and update payloads with the backend UpdateEntityRequest schema by adding support for sub_type and removing non-updatable fields that caused 400 errors.

Sequence diagram for updated entity update flow

sequenceDiagram
    actor Connector
    participant ElderClient
    participant BackendAPI

    Connector->>ElderClient: update_entity(entity_id, entity)
    ElderClient->>ElderClient: Build UpdateEntityRequest payload
    ElderClient->>BackendAPI: PATCH /entities/{entity_id}
    activate BackendAPI
    BackendAPI->>BackendAPI: Validate payload with UpdateEntityRequest
    BackendAPI-->>ElderClient: 200 OK Updated entity
    deactivate BackendAPI
    ElderClient-->>Connector: Updated entity response

    %% Payload fields after fix
    rect rgb(235, 235, 235)
        ElderClient->>BackendAPI: Payload
        ElderClient-->>BackendAPI: name
        ElderClient-->>BackendAPI: entity_type
        ElderClient-->>BackendAPI: description
        ElderClient-->>BackendAPI: sub_type
        ElderClient-->>BackendAPI: parent_id
        ElderClient-->>BackendAPI: attributes
        ElderClient-->>BackendAPI: tags
        ElderClient-->>BackendAPI: is_active
    end
Loading

Class diagram for Entity and UpdateEntityRequest alignment

classDiagram
    class Entity {
        +str name
        +str entity_type
        +str organization_id
        +str description
        +str sub_type
        +int parent_id
        +dict attributes
        +list~str~ tags
        +bool is_active
        +str owner_identity_id
    }

    class UpdateEntityRequest {
        +str name
        +str description
        +str entity_type
        +str sub_type
        +int parent_id
        +dict attributes
        +list~str~ tags
        +dict default_metadata
        +bool is_active
    }

    class ElderClient {
        +create_entity(entity) Dict
        +update_entity(entity_id, entity) Dict
    }

    ElderClient --> Entity : uses
    ElderClient --> UpdateEntityRequest : maps_to

    %% Highlight non_updatable and aligned fields
    class Entity {
        +str organization_id
        +str owner_identity_id
    }

    Entity .. UpdateEntityRequest : aligned_fields
Loading

File-Level Changes

Change Details Files
Align create_entity payload with API schema and include sub_type while dropping owner-related field not required on create.
  • Add sub_type from the Entity model into the JSON payload sent on entity creation.
  • Remove owner_identity_id from the create payload since it is no longer (or not) required/supported by the entities API.
  • Extend structured logging for entity creation to include the sub_type field.
apps/connector/utils/elder_client.py
Restrict update_entity payload to only fields accepted by UpdateEntityRequest, including sub_type and excluding organization and owner fields.
  • Document in the update_entity docstring that organization_id cannot be changed and only UpdateEntityRequest-supported fields are sent.
  • Build the update payload without organization_id and owner_identity_id to avoid extra='forbid' validation errors.
  • Add sub_type to the update payload so entity sub-type changes/updates are properly propagated.
  • Extend structured logging for entity updates to include sub_type for easier debugging and observability.
apps/connector/utils/elder_client.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • For both create_entity and update_entity, consider excluding keys whose values are None from the payload so that partial updates don't unintentionally overwrite existing fields with nulls (e.g., sub_type, description).
  • Given that organization_id and owner_identity_id are no longer sent on update, it may be worth asserting or validating earlier in the flow that these fields are not expected to change, to catch any future misuse of the Entity model before making the API call.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- For both create_entity and update_entity, consider excluding keys whose values are None from the payload so that partial updates don't unintentionally overwrite existing fields with nulls (e.g., sub_type, description).
- Given that organization_id and owner_identity_id are no longer sent on update, it may be worth asserting or validating earlier in the flow that these fields are not expected to change, to catch any future misuse of the Entity model before making the API call.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to 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