Skip to content

CLI: profiles: relationship doesn't skip mandatory validation on object load #1186

Description

@BaptisteGi

Component

infrahubctl

Infrahub SDK version

1.22.1

  • OS: macOS 26.3 arm64
  • Python: 3.13.11

Current Behavior

When an object file assigns a profile to a node through the node's real profiles: relationship, infrahubctl object load / object validate still fail with <attribute> is mandatory for every mandatory attribute the profile provides — even though the profile does supply a value, and even though this exact scenario works correctly through the UI.

This looks like the same bug reported in #908 ("Object file validation requires mandatory attributes even when a profile provides them"), which was closed by #980. However, that fix does not actually cover this case, and I don't believe there is currently any way to load an object-file-defined profile assignment without duplicating every mandatory attribute value in the object file itself.

Root cause

The mandatory-check exemption added in #980 (infrahub_sdk/spec/object.py) only skips validation when the literal string "object_profile" is a key in the object's data dict:

if "object_template" not in data and "object_profile" not in data:
    errors.extend(
        ObjectValidationError(position=[*position, element], message=f"{element} is mandatory")
        for element in schema.mandatory_input_names
        if not any([element in data, element in context])
    )

But object_profile is not a real schema attribute or relationship — I confirmed this by introspecting a live schema's relationship_names (['member_of_groups', 'subscriber_of_groups', 'profiles'] — no object_profile). The actual, documented way to assign a profile in an object file is the profiles: relationship (a list), which is what the UI uses.

This creates a no-win situation, both reproduced against a live instance:

  1. Use profiles: (the real, correct key) — the "object_profile" not in data check is True (since the key is profiles, not object_profile), so the exemption never triggers, and mandatory validation still fires:
    File 'placeholder.yml' [2] is not valid!
    1.quantity: quantity is mandatory
    
  2. Use object_profile: (the key the exemption actually checks for) — the mandatory check is correctly skipped, but a few lines later a separate loop rejects any key not in schema.attribute_names / schema.relationship_names, and object_profile isn't in either, so it fails differently:
    File 'placeholder.yml' [2] is not valid!
    1.object_profile: object_profile is not a valid attribute or relationship for TestPlaceholder
    

Notably, the unit test added by #980 (test_validate_object_skips_mandatory_check_with_object_profile) only asserts that errors with message "type is mandatory" are absent — it never asserts the full error list is empty — so it didn't catch case 2 above.

This likely also affects object_template (#895), which uses the identical pattern ("object_template" not in data) and has the identical test-assertion gap (test_validate_object_skips_mandatory_check_with_object_template has the same narrow assertion). I have not reproduced the template case against a live schema with generate_template: true, but the code path is the same, so I'd expect the same "not a valid attribute or relationship" failure if object_template is actually used as a key.

Expected Behavior

An object file that assigns a profile via the node's real profiles: relationship should not require mandatory attributes the profile supplies to also be present in the object file — matching the UI's behavior.

Steps to Reproduce

Schema (optional: false on quantity):

nodes:
  - name: Placeholder
    namespace: Test
    human_friendly_id: [name__value]
    attributes:
      - name: name
        kind: Text
        unique: true
      - name: quantity
        kind: Number
        optional: false

Object file:

---
apiVersion: infrahub.app/v1
kind: Object
spec:
  kind: ProfileTestPlaceholder
  data:
    - profile_name: some-profile
      quantity: 44
---
apiVersion: infrahub.app/v1
kind: Object
spec:
  kind: TestPlaceholder
  data:
    - name: placeholder-1
      profiles: [some-profile]

Run:

infrahubctl object load placeholder.yml

Result: 1.quantity: quantity is mandatory, despite the profile providing quantity.

Additional Information

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething isn't working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions