[Infrahub - v1.12.0b0) - 2026-10-30
Security
- Upgraded
graphql-corefrom 3.2.8 to 3.2.13, which fixes two denial-of-service vulnerabilities in the library, CVE-2026-75507 and CVE-2026-75508. The GraphQL API now rejects a query whose validation needs more than 250,000 field comparisons with a "Query is too complex to validate" error.
Added
-
Node events delivered to webhooks now identify the objects they mention: the changelog carries the node's human-friendly ID (
hfid), and each relationship peer carries its display label (peer_display_label) and human-friendly ID (peer_hfid). This applies to node mutations and to the node events a branch merge or rebase emits, so a receiver no longer has to query Infrahub to resolve the IDs. (#9671) -
Connecting a read-write
Repositorynow verifies that Infrahub can push to the remote, not only read from it. A credential that can read but not push is caught when the repository is connected, and the connection is rejected with a credential error naming the cause, rather than the problem surfacing later at the first branch creation or merge. Read-only repositories are unaffected. A push that fails at the transport level (for example an expired token or a refused connection) is now classified and recorded on the repository's operational status the same way a fetch failure already was.The write check is effective on Git servers that enforce write authorization when advertising the receive-pack service (such as GitHub and GitLab). It confirms repository-level write access and does not evaluate branch protection, push rules, or pre-receive hooks. (#10637)
-
Added Repositories and Git state columns to the branches list, showing each branch's Git repositories with the worst Git state first and a link to the branch for the full list.
-
Added a "Number" input to the "From pool" tab of a number attribute in object forms, so you can type a number and record it in the selected number pool; when editing, typing a number in the "Value" tab removes the number from its pool.
-
Added a Generators section to an object's Actions menu that runs a Generator for that object only, listing the Generators whose target group contains objects of the same kind.
-
Added a Repository activity card to the repository page, which shows the run working on the repository now with its step, branch and running time, who holds the repository lock, and what the last run of each operation changed or failed on.
-
Added a proposed change check that fails when the last object import of a repository on the source branch failed or has not completed, blocking the merge until the import succeeds.
-
Added a repository sync status indicator to the application header. It turns red with a pulsing dot when any Git repository on the branch you are viewing has failed to import, on every page, and links straight to the repository list filtered to those failures.
It reads repository sync status rather than task state, so an import that left the branch broken is reported even when the task that ran it finished successfully. When nothing is failing it links to the full repository list, and it always reports current status regardless of the time-frame selector.
-
Added an alpha dark theme that follows the operating system's appearance by default, with System, Light, and Dark available from the Theme option in the account menu.
-
Added pan and zoom to SVG files in the artifact and file viewers: drag to pan, and zoom with the mouse wheel or the zoom in, zoom out, and reset buttons.
-
Added telemetry to find which component makes an instance slow. When the Python SDK sends the trace context, a background task shares one trace with the API calls and database queries it sends.
INFRAHUB_TRACE_SAMPLE_RATIOsets the share of recorded traces (default 0.1), and an administrator can raise it for up to 24 hours without a restart through/api/troubleshooting/trace-sample-ratioorinfrahubctl troubleshooting trace-sample-ratio. New metrics show long query and request durations, connection pool usage and task worker queue delays. Traces no longer contain single sign-on secrets and mask personal data, the bundled Grafana dashboards work in any Grafana, and the Compose observability stack turns tracing on.gunicornmust start with--config backend/infrahub/serve/gunicorn_config.py, as the Compose files and Helm charts do. -
Added the GraphQL API for repository git visibility.
InfrahubRepositoryCommitsanswers for the branch you are viewing with the remote branch or tracked ref it follows, the commit Infrahub has imported, and a paged commit log read live from a worker's local copy, each commit labelled as imported, pending, history, unrelated or at the remote head. On a branch that does not sync with Git, it lists the repository's own default branch and labels the commits the branch does not run yet as not on this branch, since only a rebase brings them to the branch, except the newest, which stays the remote head; on the branch a repository was added on, those commits stay pending import until the branch is merged. It reports when the remote history was rewritten, when the imported commit no longer exists in the local copy, and when a read-only repository's tracked branch or tag has been deleted upstream as of the worker's last fetch, in which case it still lists the history Infrahub is running. A worker that has no local copy yet answers that the log is not available and starts a single background clone that reaches every worker; a read-write repository that has imported nothing yet is instead left to its next sync, which creates the copy along with the first import.InfrahubReadOnlyRepositoryCheckRefsis published alongside it so consumers can build against the full surface. -
Added the
InfrahubRepositoryActivityGraphQL query, which shows the runs working on a repository now, the last run of each operation and which worker holds the repository lock, with the same answer on every branch. -
Added the
InfrahubRepositoryBranchStatusGraphQL query, returning one row per branch with the repository'scommit,sync_statusandinternal_statusas that branch resolves them, plusreffor a read-only repository, filterable withname__value,partial_match,status__value,sync_status__value,internal_status__value, andown_values_only. -
Added the
last_rewrite_previous_commit,last_rewrite_commit,last_rewrite_atandrewrite_countattributes to Git repositories, which record per branch the commit Infrahub had imported before the remote history was rewritten, the commit it moved to, when that happened and how many rewrites the branch has seen, including those on the default branch before the branch was created, and which do not count a change of the repository's default branch as a rewrite; on a read-only repository, "Import latest commit" updates them when the tracked branch was force-pushed, and does not count a change ofreforcommitas a rewrite unless it runs while that change is still being applied. -
Added the allocation scopes of a number pool to its details page. The page lists the pool's allocation scopes, sorted by usage and searchable, and opens the ranges and allocated numbers of one scope on the same page, kept in the address so it can be shared. A pool with an allocation scope no longer shows ranges and numbers for the whole pool, and the header names the fields the pool is scoped by.
-
Added the branch's Git repositories and tasks to the branch details page, on branches other than the default branch. The repositories table shows each repository's Git state and commit. When an import fails, the page shows the last error line of the failed import when it can find it, and when a repository's remote can't be reached, it shows a warning that the commit shown may be out of date. The tasks table lists the tasks that ran on the branch.
-
Added the handling of a failed push to the Git remote after a branch merge. When Infrahub cannot push the merge of a branch to the remote of a read-write repository, the merge stays complete in Infrahub and waits in the push queue of the repository until the push succeeds or a user abandons it. Infrahub retries the push automatically when the cause can clear by itself, for example an unreachable remote, and records the cause and the message of the remote on the repository. Nine new read-only attributes of the repository, such as
delivery_status,delivery_failure_causeanddelivery_queue, show the push state through GraphQL. The newInfrahubRepositoryDeliveryRetrymutation pushes the pending merges again, and the newInfrahubRepositoryDeliveryAbandonmutation drops them.The details page of a read-write repository shows the push state in a Push to remote card: the status, the cause and the required action of a failed push, the message of the remote, the pending merges, and the last abandoned push. The Retry push and Abandon pending push actions of the repository menu push the pending merges again or drop them, and a disabled action shows why it is unavailable.
While pushes are pending, Infrahub does not import the remote default branch of the repository, refuses Reimport current commit and the conversion to a read-only repository, keeps the remote source branch of a pending merge, and holds the artifacts, Generators and Python computed attributes that the repository defines until the push succeeds or the queue is abandoned. If someone pushes to the remote default branch while pushes are pending, Infrahub refuses to merge another branch that changes the files of the repository until the pending pushes reach the remote or are abandoned. Infrahub also records a pushed commit that a later rewrite of the remote default branch removed, and stops the fetch and the push of the pending merges when an HTTP or HTTPS remote stalls.
When Infrahub cannot start a background task in the task manager, or cannot follow the task until it ends, an API request that waits for the result of that task now fails with the HTTP status 503 (service unavailable) instead of 500.
A revert to an earlier version keeps the data valid, because the earlier version ignores the nine new
delivery_*attributes of the repository. Two effects remain after a revert. Merges still in a push queue are never pushed: push them by hand, or merge again. Held regeneration is never released: run a full regeneration of the default branch. -
Choose which columns a list view shows. Every schema-driven table — the object list, relationship
tabs, and the IPAM address and prefix lists — now has a Columns control. Wherever column headers
offer a menu, that menu also carries a Hide column shortcut; relationship tabs have read-only
headers, so there the Columns control is the way. The control stays open as you tick columns on and
off, so setting up the view you want is a single visit.Your choice lives in the URL, so a reload keeps it and the link can be shared with a colleague who
will see the same view. On the object list you can also reveal attributes the schema marks as
secondary (display: "extra"), which previously had no way to appear in a list at all. Only the
columns you change are recorded, so a schema that later gains a column shows it on an existing link.
Reset restores the schema's own layout. -
Connecting a repository now checks that its configured default branch exists on the remote, as part of the connectivity check that already runs. When the branch is absent, the request is rejected with an error naming the branch Infrahub looked for and, where the remote has one, the branch it uses as its own default. No repository is left behind - previously the repository was created and only failed later, during its first synchronization. A default branch that exists but differs from the remote's own default is a supported configuration and is accepted. Read-only repositories are unaffected: their
refmay be a tag or a commit hash, which a branch listing cannot confirm. -
Read-only repositories are now checked for upstream movement of the refs they track, so a branch or tag that advances on the remote is noticed without waiting for someone to trigger an import. The check runs on a schedule. A user with permission to update the repository can also start it from the "Check remote now" button on the repository's Commits tab, or through the
InfrahubReadOnlyRepositoryCheckRefsmutation, which previously accepted a request and did nothing. Every check that reaches the remote records a check time, which the Commits tab shows even if the remote has not moved. A repository whose tracked ref has moved has the new objects brought into every worker's copy, while the commit Infrahub has imported stays exactly where it was: nothing here writes the tracked commit, triggers an import, or changes which commit a worker has checked out.INFRAHUB_GIT_READ_ONLY_REFS_CHECK_INTERVAL_MINSsets how long the system waits before checking one repository again, defaulting to 15 minutes. Lengthening it is the way to make the check less frequent; an idle repository costs one refs listing per interval and transfers nothing. A repository whose remote cannot be reached is recorded with the reason and retried sooner than a full interval, without holding up the others.When the check finds that a tracked branch or tag has been deleted from the remote, the repository's sync status shows "Tracked Ref Missing" on the default branch, if it tracks that ref, and on every branch that set its own ref to it. Those other branches fail their proposed-change check and cannot be merged. A branch that only inherits the default branch's ref is not affected. To recover, restore the ref on the remote or change the repository's ref, then run "Reimport current commit". A reimport run while the ref is still missing keeps the status.
-
See at a glance how a repository stands on every branch. A repository's detail page now carries a
Branches card listing one row per branch — the branch name, the branch status, its sync status,
the commit shown for that branch, and, for a read-only repository, the ref it tracks — with the
default branch marked and the total shown beside the title.The card is paginated, and searching or filtering narrows the set on the server rather than in the
browser, so the count and the pages always describe the same set. Filter by branch name, branch
status or sync status, for example to list only the branches whose import failed, and sort by when
a branch was created or last updated. The page, the filters and the sort
all live in the URL, so a reload keeps the view and the link can be shared with a colleague.A repository's details are also split in two, so it is clear which values describe the whole
repository and which describe only the branch you are on: a repository-wide card, then an On this
branch card captioned with the branch name, then the branches card. Switching branch changes the
second card alone. Every other kind of object keeps its single details card. -
The daily anonymous telemetry report now includes the CPU and memory available to the API server and the task workers, and the CPU count and memory set for the database. Two new blocks,
serverandtask_workers, count the processes of each component the same wayworkersdoes. Each also reportsprocesses_per_container, the number of processes that share one container, and aper_containerobject with the CPU count a process in that container can use (processor_available), the CPU limit set on the container (processor_assigned), and the memory and free memory of the container (memory_total,memory_available). Multiplyingper_containerbyactiveand dividing byprocesses_per_containergives the total for the component. The database block gainsprocessor_assigned, the CPU count set for the Neo4j parallel query engine, andmemory_heap_max_sizeandmemory_pagecache_size, the Neo4j heap and page cache sizes as Neo4j reports them, such as1.00GiB, ornullwhen not set. Theworkersblock and every other existing field are unchanged, and a new figure that cannot be read is reported asnullwithout affecting the rest of the report. -
The repository page has a new Commits tab. Once Infrahub can read a repository's commit history, the tab lists the commits of the branch you are viewing, newest first, with the short hash, summary, author and date of each one. It marks the commit Infrahub has imported and the current head of the remote, shows how many commits are pending import, and says when the tracked ref was rewritten so the imported commit is no longer part of its history. On a branch that does not sync with Git, for a read-write repository that was not added on that branch, the tab lists the history of the repository's default branch, says how many commits the branch is behind it or that it is up to date, and marks those commits as behind. When the branch is behind, has diverged from the default branch, for example after a force push, or uses a commit that is missing from the remote, it asks for a rebase, which moves the branch to the commit Infrahub's default branch uses. For a read-write repository added on that branch, the tab says the next sync imports its pending commits. The tab title shows how many commits are waiting and whether an import or a rebase is needed, and a warning when the history was rewritten, the imported commit is missing from the remote or the tracked ref was deleted. The top of the tab states whether the branch is up to date, behind, diverged or waiting for an import, says what brings the missing commits, and shows the tracked ref and when the remote was last checked. It offers Import latest commit and Check remote now on a read-only repository, and Rebase branch on a branch that does not sync with Git, after a confirmation that the whole branch is rebased onto the default branch. It also offers Check remote now when the commit log of a read-only repository is not available, and says when a read-only repository has imported no commit yet and offers Import latest commit. Check remote now is offered only for a read-only repository that is active on the branch you are viewing, so not for one added on that branch. When the tracked ref of a read-only repository no longer exists on the remote, it says to change the tracked ref in the repository's Edit form or restore it in Git. While an import, a rebase or a check runs, the tab says so. A disabled action says why it is disabled: you are not signed in, the branch needs a rebase, is being merged, is merged or its merge failed, you lack the permission, or the branch is the default branch. Each commit has a menu to copy its full hash or, for repositories hosted on GitHub, view the commit on GitHub.
Until Infrahub can read a repository's commit history, the tab says the commit log is not available.
-
Uniqueness constraint violations on GraphQL mutations now return the catalogued
UNIQUENESS_VIOLATIONcode instead of falling back toUNDEFINED_ERROR. Theextensions.datapayload carriesnode_kindandfields, so consumers can identify the colliding constraint members (which may be relationships as well as attributes) without parsing the error message. HFID collisions resolve to the same code. -
When a read-write repository's
default_branchdiffers from Infrahub's default branch, Infrahub cannot import a remote branch with the same name as Infrahub's default branch. Infrahub now records that skipped branch as a warning in the repository's Tasks tab, not only in the worker's process log. The warning appears when you add the repository on Infrahub's default branch, and again on any synchronization that imports a branch or detects a new commit on the skipped branch. Successful synchronizations where nothing changed on the remote add no task. With more than one task worker, a push to the skipped branch is not always reported, and the same push can be reported more than once. -
When allocating a resource from an IP pool through a relationship that points at the generic
BuiltinIPAddressorBuiltinIPPrefix, the target object kind can now be chosen instead of
always using the pool'sdefault_address_type/default_prefix_type. In the UI, the
relationship's existing "Kind" picker selects which concrete kind is allocated; over GraphQL,
passaddress_type(new onIPAddressPoolInput) orprefix_typeinsidefrom_pool.The requested kind is validated server-side: it must be one of the kinds implementing the
relationship's peer generic, and it cannot be changed on an identifier that already holds a
reservation. Note thatprefix_typewas previously accepted onIPPrefixPoolInputwithout
any validation, so a client sending a kind unrelated to the relationship's peer now receives
an error instead of an unexpectedly-typed node.Object templates are not covered: a template's
<relationship>_from_resource_poollink stores
only the pool, so an object created from a template still allocates the pool's default kind.
Sending a target kind or a prefix length on that link previously made the mutation fail, and is
now correctly omitted. -
When the import of a Git repository branch fails, the task log now names the import step that was running when the import stopped, the steps that ran before it and the steps that did not run, or states that nothing was imported when the failure happened while the repository was read. A step with nothing to import is listed among the steps that ran. A failure caused by a connection or credential error is not followed by this summary.
-
CoreGenericRepositorynow defines acommitattribute, so the current commit of any repository can be read without knowing whether it is a managed or a read-only repository. Both concrete kinds continue to override the attribute with their own branch scope, so their behaviour is unchanged.
Changed
-
Improved rendering performance of the proposed change diff view: offscreen diff cards skip layout and paint while scrolling large diffs. (#infp-677)
-
Editing a repository's
.infrahub.ymlno longer regenerates every artifact and re-runs every Generator in that repository. The manifest used to be part of every Transformation's and Generator's dependency closure, so a comment-only edit, or an entry belonging to an unrelated definition, re-rendered everything; a manifest edit now affects only the definitions whose own configuration it changed, unless a definition still falls back to regenerating on any file change or names.infrahub.ymlunder itswatch.files. On the first import after upgrading, fingerprints are recomputed for Python Transformations, Generator definitions, and Python-Transformation-backed artifact definitions, which regenerates their artifacts, re-runs those Generators once, and recomputes once every computed attribute backed by a Python Transformation. (#9643) -
Merging a branch, through the
BranchMergemutation,branch.mergein the Python SDK or a proposed change, is now refused when the last import of a repository on that branch failed or has not completed. The branch stays open, and the error names each repository and how to clear it: push a fix, run "Reimport current commit" or set the repository to inactive on the branch for a failed import, or run "Reimport current commit" for an import that does not complete. (#10498) -
A branch created in Infrahub with "Sync with Git" turned off no longer receives commits when a branch with the same name is later created in a connected Git repository, whether or not branch import rules are configured. Infrahub used to import commits from that Git branch into the Infrahub branch, although merging the branch never sent its changes back to Git. After the upgrade, such a branch keeps the last commit it imported and receives no new ones. (#10684)
-
Breaking: Changed the format of the
trace_idlog field of the API server from a0xhexadecimal number without leading zeros, for example0xaf7651916cd43dd8448eb211c80319c, to the 32-character form that Tempo and Grafana use, for example0af7651916cd43dd8448eb211c80319c. Update the log queries and alerts that readtrace_id. -
A Git repository import now fails, and sets the branch to an import error, when an entry in
.infrahub.ymlcannot be used: a schema path that does not exist, a schema directory that contains no.yml,.yamlor.jsonfile, or a Jinja2 transform whose template file is missing, is empty, is not UTF-8 text, cannot be parsed or is outside the repository. Previously the import skipped a schema path with a warning and continued, and registered the Jinja2 transform, so the template problem appeared only when an artifact was generated. After the upgrade, the next import of a branch whose.infrahub.ymlhas one of these entries shows an import error, and none of that import is applied until the entry is fixed. -
A live change to a node that feeds a Python transform computed attribute no longer starts duplicated recompute tasks. A change to a node the transform query reads now recomputes only the attributes that query feeds, on the nodes that read the changed node through it, instead of every Python computed attribute of every kind subscribed to any query group that holds the changed node. The stored values are the same.
The automations that carry this are rebuilt on the next reconcile, which
infrahub upgradeperforms, so the previous behavior continues until then. -
A merge or a rebase no longer starts one recompute task per changed node for Python transform computed attributes. It now derives the affected attributes from the whole change set and submits one recompute per affected attribute per batch of changed nodes, as it already did for Jinja2 computed attributes, display labels and human-friendly ids. The stored values are the same.
An attribute whose transform query is not pinned to a single object recomputes its whole kind instead. Pin the query to get the narrowed recompute. See Single-target queries.
-
Added a header to the number pool details page. It shows whether the schema manages the pool and what the pool allocates to. Its Actions menu disables Edit, Groups and Delete on pools that the schema created.
-
Changed the number pool details page to list the pool's ranges in the order the pool fills them, with how much of each is used, next to a table of the numbers in the selected range that shows the node holding each one, its branch and whether the pool allocated it or a user provided it. The table can be filtered by source and by branch.
-
Changed the number pool form so that creating a pool sets its node, number attribute, optional allocation scope and several weighted ranges, each of which can leave its start or end empty, in one save, and editing a pool changes its name, description and ranges while its node, attribute and scope stay read-only.
-
Clarified the description of the
default_branchattribute on repositories. It now states that the value is the remote branch Infrahub maps onto its own default branch, and that it does not have to be the remote's default branch. -
Deprecated attributes and relationships of the nodes that Infrahub provides no longer produce a warning in the server logs each time the schema is processed, including at startup. Deprecated attributes and relationships of your own schema nodes still produce this warning.
-
Limited how long Infrahub waits for a task worker when it checks the connection to a repository you add or when you check its connectivity, fetch a file from it, or view its commits: after the time set by the new
INFRAHUB_BROKER_RPC_TIMEOUTsetting (120 seconds by default) the request now fails with an error instead of waiting indefinitely, and if no worker answers while you add a repository, Infrahub removes it so that you can add it again. -
Post-merge regeneration now narrows to the affected members when the changed data is read through a relationship (for example an owner's name rendered by an artifact, or an interface's field on a device), instead of regenerating every member of the definition. Changes that cannot be attributed to specific members unambiguously still regenerate the whole group.
-
Reduced the number of database queries the repository sync runs when reading each branch's commit and internal status. The read now costs a small fixed number of queries for the repository nodes plus one query per 100 branches, instead of one query per branch.
-
Rewrote the key concepts documentation with concise explanations, infrastructure examples, and diagrams.
-
Upgraded the frontend
zodvalidation library from 4.4 to 4.5. -
When a change to a related node alters a display label or human-friendly ID, only the artifacts and Generator instances of the targets that show that label or ID are now regenerated after a merge or in a proposed change, instead of every target of the definition.
Fixed
-
Fixed a GraphQL query that selects the same top-level field more than once (for example
BuiltinTag { count }alongsideBuiltinTag { edges { ... } }) returning only the first occurrence's selection and dropping the rest. When a dropped selection held a non-null field the whole response failed with a "Cannot return null for non-nullable field" error. The selections from every occurrence are now merged into one result. (#5430) -
Fixed the synchronization of a Git branch whose history was rewritten and force-pushed: the branch now follows the new remote history and its objects are imported again with no user action, instead of the repository going to the error status with a merge conflict that did not exist. (#6299)
-
Common Git repository import failures caused by the repository's content, such as an invalid schema, object file or query, are now logged once as a readable message that names the failing entry and file in
.infrahub.yml, without a Python traceback. A failure the import does not recognise is still logged once with its traceback. A failed import of one branch no longer stops the import of other branches, except for a connection or credential error, which still stops the repository's sync for that cycle. (#7498) -
Fixed a merge of a branch that syncs with Git, through a Proposed Change or directly, that could skip the Git merge or put commits removed by a force push back in the Git repository, when Infrahub had not yet recorded the latest commit of the branch. Infrahub now refuses the merge until it records the latest commit pushed to the branch and to the branch it merges into. The branch stays open, so you can merge again after the next synchronization. When the Git repository is rewritten during the merge, Infrahub pushes nothing, keeps the merge in the push queue of the repository, and records the cause on the repository. (#9499)
-
Branch merge and proposed change review events are now emitted on the default branch, so webhooks scoped to the default branch reliably match them regardless of which branch triggered the change. (#9761)
-
Fixed read-only repositories failing to follow a tracked tag that was moved upstream: an import either failed or kept the commit the tag used to point at, and workers other than the one running the import could not pick up the new commit. (#9826)
-
Removing the last object file from a repository, or clearing the
objects:list in.infrahub.yml, now deletes the objects that file defined. Previously an import pass that ended up tracking no objects skipped the cleanup entirely, so those objects stayed in the instance as orphans and the repository's tracking group kept listing them. Removing one object file among several already worked. The empty case also covered removing every object file except those that define Generator actions or trigger rules, since those are imported in a later pass with a tracking group of their own.Objects left orphaned by earlier versions are deleted on the first import after upgrading. If you worked around this by removing object files one at a time, or by keeping a placeholder object file, neither is needed any more.
An object that cannot be deleted because another node still references it through a mandatory relationship no longer aborts the rest of the cleanup. Every other object is still removed, the failures are reported together, and the objects that could not be deleted stay in the tracking group so the next import retries them. The import itself continues: menus, checks, Generators and artifact definitions are still applied, and the failed deletions are reported as a warning on the import task rather than failing the repository sync. (#10134)
-
Fixed GraphQL queries silently returning missing or null values when a selection reached a field through a fragment nested inside an inline fragment, or selected the same field more than once under one response key through repeated fields, sibling fragment spreads, or sibling inline fragments. The backend now reads the union of everything the query selects at every nesting depth instead of dropping or overwriting the overlapping branches; a query whose dropped field was non-null previously failed outright with a "Cannot return null for non-nullable field" error. (#10653)
-
Infrahub now refuses a Number attribute value below -9223372036854775807 or above 9223372036854775807 with a validation error; such values previously caused a server error, except -9223372036854775808, which was stored. (#11247)
-
A Python computed attribute that shares its transform with another computed attribute is now recomputed automatically. The automations were indexed by transform name, so out of several attributes fed by one transform only one got an automation. A sibling attribute on another kind was then never refreshed when a node changed, and kept the value of its last successful compute. Each attribute now gets its own automation for a change to a node of its own kind, and the transform's query automations cover every attribute it feeds. A schema change on a branch now also recomputes the Python computed attributes that branch shares with the default branch.
-
A Python transform or check whose
class_nameis not defined in its module now fails the branch import with a message that names the entry, instead of being skipped silently and having its existing definition deleted from Infrahub. -
A branch merge that Infrahub refuses for a reason you can fix, such as unresolved conflicts, a failed repository import or a repository that is not synchronized, no longer shows a Python traceback in the task log. The log keeps the message that explains why the merge was refused.
-
A branch merge that is refused because an earlier merge failed now says that an administrator must recover that merge, instead of reporting a merge in progress. A merge refused because the remote of a repository rejects the credentials now logs the error output of Git as a warning in the task log.
-
A repository whose default branch is not Infrahub's own default branch could intermittently be read on
the wrong branch. Once a worker had cloned the repository, later operations on that worker - artifact
generation, transforms, generators, computed attributes and proposed change checks - fell back to
Infrahub's default branch instead of the repository's configured default branch. Depending on the
remote, this produced output built from the wrong branch's files or a failure naming a branch that was
never configured. The configured default branch is now resolved every time the repository is accessed,
so all workers behave the same whether or not they already had a local copy. -
Computed attributes, display labels, human-friendly ids and Profile refresh no longer recompute twice for a change made on a branch that carries its own schema. The duplicate work appeared once two or more branches differed from the default branch, and it was most visible on a rebase, where every replayed node was processed twice. The stored values were always correct.
-
Fixed Infrahub's default branch no longer receiving commits from a repository when branch import rules are configured and the repository's default branch has a different name, such as develop, that no rule matches.
-
Fixed Python computed attributes that could stay empty, and artifacts that could be missing, after you added a read-write repository. When the periodic Git synchronization imported the new repository first, it imported the objects before it recorded the repository's commit, so the computed attribute and artifact tasks failed and did not run again.
-
Fixed a branch merge being recorded against an external repository even when the remote rejected the push (for example on a protected branch); the rejection now fails the repository merge task with an error describing it, and Infrahub keeps the last commit the remote actually accepted.
-
Fixed a failed import of a repository branch showing in the repository's task log on the default branch instead of on the branch that failed.
-
Fixed a read-only repository that stayed on its old commit when its
reforcommitchanged through an upsert, for example withinfrahubctl object loador the SDKsave(allow_upsert=True): the upsert now pulls and imports the new target, as an update does. -
Fixed a schema load taking the
number_pool_idof a NumberPool attribute from the loaded file: the load now ignores it with a warning, so a schema exported from another instance gets its own number pools instead of pointing to pools that do not exist. -
Fixed converting an object to another kind freeing a number it held from a number pool, which let the pool hand the same number out again. The pool keeps accounting for the number when the new kind is one the pool tracks, such as another kind inheriting from the generic the pool is attached to.
-
Fixed long attribute and relationship labels on the object details and convert views wrapping onto several center-aligned lines or overlapping the value: a long label now ends with an ellipsis, and hovering it or moving to it with the keyboard shows the full label in a tooltip.
-
Fixed one Git branch that failed to synchronize preventing the other branches of the same repository from updating on the other workers, and one failing repository stopping the synchronization of the repositories after it.
-
Fixed stray style names being written onto every row of a tree or a list. Internal state names from the underlying component library were passed through as if they were style names, which changed nothing visually but could have collided with a real style name added later.
-
Fixed the
@expanddirective being ignored when the node it annotates is selected through a named fragment (for exampleedges { ...EdgeFields }withnode @expandinsideEdgeFields); the node's attributes are now expanded the same way as when the selection is written inline. -
Fixed the count at the bottom of a table being covered by the other footer cells when you scroll the table horizontally.
-
Fixed the node events Infrahub emits for the peers of a relationship change. A peer reached through several changed relationships now receives one event instead of one per relationship. Adding or swapping a one-cardinality peer records the protection, owner and source of the new edge, removing one keeps the removed parent, and a peer that holds the mutated node as its parent names it as parent and root node.
-
Focusing the Infrahub logo in the sidebar with the keyboard now shows the full focus ring: a border in the focus colour with space between it and the logo.
-
Telemetry snapshots are now still produced and sent when Infrahub cannot read the database host's memory and processor information; that field is reported as empty instead.
-
The scheduled repository sync now reads a repository's operational status from the database instead of always seeing
unknown, so a repository that is online again gets tagged when a sync fails. -
Viewing the files changed in a branch no longer fails when that branch contains a repository that was added or synced for the first time while the branch was open, or one whose commit was removed. Such a repository has no earlier commit to compare against, and the resulting error stopped the entire comparison, so the files changed in the branch's other repositories were not listed either. A repository with nothing to compare against is now left out of the list, and the remaining repositories report their changed files as usual.
-
RelationshipRemovenow refuses to remove a node whose own side of the relationship is mandatory with a single peer, instead of leaving that node without the peer its schema requires.
Housekeeping
- Consolidated the frontend on a single linter and formatter.
frontend/packages/uiand
frontend/packages/graphusedoxlint+oxfmt, which nothing in CI ever ran, while
frontend/appused Biome; both packages had therefore been unchecked since they were created.
Biome now owns the wholefrontend/pnpm workspace from one root configuration, and the
frontend-lintCI job gates the app and the packages in a single step. - Fixed intermittent failures in the frontend unit test job. A dependency discovered during a test run made the page reload, which discarded module mocks and failed whichever test file was running at the time. Those dependencies are now loaded before the run starts, including ones owned by other packages in the frontend workspace, which the previous test configuration failed to resolve.
- The BLE (flake8-blind-except) ruff rule is now enforced — blind
except Exceptionhandlers are either narrowed to the specific exception types they guard against or carry an explicit justified# noqa: BLE001.