Skip to content

bug: file_object_content* filters fail with 404 due to /api/files URL path mismatch #954

@PhillSimonds

Description

@PhillSimonds

Component

Python SDK

Infrahub SDK version

1.9.0b0 (submodule commit 44a7cccf57ee3e20a2f7946b9e505135b5d7387a, pinned by Infrahub release-1.9)

Current Behavior

All three file_object_content* Jinja2 filters shipped in opsmill/infrahub-sdk-python#889 and #904 fail at runtime with HTTP 404. The SDK constructs URLs under /api/files/..., but the Infrahub backend only routes these endpoints under /api/storage/files/.... Every call to file_object_content, file_object_content_by_id, or file_object_content_by_hfid raises JinjaFilterError: Client error '404 Not Found', and the corresponding artifact goes to Error status.

SDK URLs in infrahub_sdk/object_store.py (commit 44a7ccc):

```
line 105: f"{self.client.address}/api/files/by-storage-id/{storage_id}"
line 110: f"{self.client.address}/api/files/{node_id}"
line 116: f"{self.client.address}/api/files/by-hfid/{kind}?{params}"
line 191: (sync) same
line 196: (sync) same
line 202: (sync) same
```

Backend actual routes (from /api/openapi.json):

```
/api/storage/files/by-storage-id/{storage_id}
/api/storage/files/{node_id}
/api/storage/files/by-hfid/{kind}
```

A raw curl confirms:

```
curl /api/files/by-storage-id/ → HTTP 404 "endpoint does not exist"
curl /api/storage/files/by-storage-id/ → HTTP 200, returns file content
```

The /api/files/* prefix is not mounted anywhere in the server. The SDK's own unit tests at tests/unit/sdk/test_infrahub_filters.py hard-code the wrong URL (`FILE_BY_STORAGE_ID_URL = "http://mock/api/files/by-storage-id\"\`) in their mocks, so the test suite passes against the wrong contract — this is how the bug shipped unnoticed.

The bug has been present since the filters were introduced (PRs #889 and #904) and is still on the latest tip of `origin/infrahub-develop` (commit `a203aac`); the diff of `object_store.py` between the release-1.9 pin and that tip is empty.

Expected Behavior

  • `file_object_content(storage_id)` returns the file's raw content for a valid `CoreFileObject` storage_id.
  • `file_object_content_by_id(node_id)` returns the file's raw content for a valid node UUID.
  • `file_object_content_by_hfid(hfid, kind=...)` returns the file's raw content for a valid HFID.
  • SDK unit tests assert the correct URL (`/api/storage/files/...`) so that contract drift is caught.

Steps to Reproduce

  1. Start Infrahub 1.9 (e.g. `uv run invoke demo.start` against `release-1.9`).

  2. Load a schema that extends `CoreFileObject`, e.g. `TestingFileBlob` with a `label` attribute.

  3. Upload a file object via the GraphQL multipart mutation:

    ```graphql
    mutation CreateBlob($file: Upload!) {
    TestingFileBlobCreate(data: {label: {value: "blob_a"}}, file: $file) {
    object { id, hfid, storage_id { value } }
    }
    }
    ```

  4. Register a Git repo with a Jinja2 transform containing any of:

    ```jinja
    {{ '<storage_id>' | file_object_content }}
    {{ '<node_id>' | file_object_content_by_id }}
    {{ '' | file_object_content_by_hfid(kind='TestingFileBlob') }}
    ```

  5. Observe the artifact status → `Error`. Worker logs contain:

    ```
    JinjaFilterError: Filter 'file_object_content': failed to retrieve content for storage_id:
    — Client error '404 Not Found' for url 'http://server:8000/api/files/by-storage-id/'
    ```

Additional Information

Suggested fix (minimal): change six lines in `infrahub_sdk/object_store.py` to use `/api/storage/files/` prefix. Also update `tests/unit/sdk/test_infrahub_filters.py` to match the correct URL, otherwise the tests will silently pass against a regressed contract.

Alternative: add an `/api/files/*` alias router in the Infrahub backend. Cleaner external URL surface, but loses the `storage/` grouping that matches the rest of that namespace.

Detection gap: the SDK's unit tests use mocks that match the buggy URLs. An integration test that exercises each filter end-to-end against a live backend would have caught this at PR review.

Full analysis and test log: `dev/specs/infp-504-artifact-composition/test-report.md` in opsmill/infrahub release-1.9.

Related: INFP-504, IFC-2275, opsmill/infrahub PR #8705.

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