Infrahub - v1.11.0b1
Pre-releaseInfrahub 1.11.0b1 release notes
| Release Number | 1.11.0b1 (prerelease) |
| Release Date | 04-08-2026 |
| Tag | infrahub-v1.11.0b1 |
Infrahub 1.11.0b1 is now available as a prerelease.
1.11.0b1 is a beta build, published ahead of the general availability (GA) release of 1.11.0. It is meant for testing and feedback, not for production environments. Anything described in these notes, including the breaking changes below, may still change before GA. Please report issues on GitHub.
This prerelease previews changes that make large environments more predictable to operate. Regeneration, recomputation, and validation now align more closely with the scope of each change, while branch operations and Proposed Changes receive priority over background tasks. New merge recovery and webhook visibility also help you resolve operational issues faster.
Artifact generation now deletes an artifact when its target object is no longer a member of the artifact definition's target group.
- If any workflow reads those artifacts, capture their content before the target is removed from the group. The deletion happens on the next full generation pass over the definition — after a merge, a definition update, or a
generatecall with no node filter.
See Breaking changes for full details.
The Infrahub container image now includes Python 3.14 (from 3.13) and Neo4j 2026.05.0 (from 2025.10.1). Python Transformations also change how they declare their dependencies.
- Plan a Neo4j upgrade to 2026.05.0 if you run your own database rather than the version shipped with Infrahub.
- Declare
watch:on any Python Transformation that imports modules from outside its own package directory. Without it, the Transformation recomputes its computed attributes on every commit to its repository. Jinja2 Transformations no longer need it — see Recompute computed attributes only when their inputs change.
See Upgrade notes for full details.
Release highlights
Regeneration and recompute
- Merge or rebase a branch and the affected computed attributes, display labels, and human-friendly IDs recompute in one combined pass instead of one job per node. See Reduce recompute time after a large merge or rebase.
- Commit to a linked repository, or change the schema, and only what depends on that change is recomputed and regenerated. See Recompute computed attributes only when their inputs change.
- Open a Proposed Change and validate only the constraints your change could break, rather than every kind in the schema. See Validate only the constraints a change can violate.
Task and API priority
- Create a branch, merge, diff, or open a Proposed Change while the instance works through a backlog, and your action starts promptly instead of queueing behind it. See Run interactive actions ahead of background work.
- Keep using the web UI while heavy background processing runs, because lower-priority requests are rejected first under sustained load. See Keep the UI responsive when the instance is busy.
Merge protection and recovery
- Recover a merge whose worker stopped partway through with
infrahub recover merge, which rolls back the partial merge and reopens the branch. See Recover from a failed merge. - An interrupted merge no longer leaves the default branch half-merged, because writes to both branches are refused while a merge runs. See Recover from a failed merge.
Inspect, retry and cancel webhook deliveries
- Open any webhook delivery to see the request, the response, and the number of attempts, then retry it or cancel one still running. See Inspect, retry and cancel webhook deliveries.
Schema and data modeling
- Store a bare IP address, with no prefix length or netmask, using the new
IPAddressattribute kind. See Store a bare IP address with theIPAddresskind. - Submit a schema and see which fields Infrahub did not apply, instead of having them ignored silently. See See which fields a schema load does not apply.
UI improvements
- Sort any object, IP address, or prefix list from a column header or the toolbar, and share the sorted view by URL. See Sort object lists from the UI.
- Set the date format and timezone you read timestamps in, or an organization-wide default for every user. See Choose the date and time format for the UI.
Regeneration and recompute
Merge a branch, update the schema, or push a commit to a linked repository, and Infrahub regenerates artifacts, re-runs Generators, recomputes derived values, and validates constraints. Each of those is now narrowed to what the change actually affected. Some cases still run in full — see What this does not cover.
Regenerate only what a merge actually changed
Merge a branch and only the artifact and Generator definitions whose inputs that merge changed are regenerated, for only the objects it affected. Merging previously regenerated every definition on the branch, for every member of its target group — one artifact per member. Across the scenarios used to validate this work, the number of regeneration tasks created after a merge fell by between 73% and 100%.
- A merge reads its diff to decide what to run. A definition is regenerated when its GraphQL query, its definition object, or its code changed, and its members are narrowed to the objects the merge changed.
- If a merge changes nothing that a definition reads, that definition is not regenerated at all.
- When a merge runs a Generator, Infrahub waits for the Generator to finish, then regenerates the artifacts built from the objects that Generator created or changed.
- When Infrahub cannot determine what a change affected, it regenerates every member of that definition rather than leave an artifact stale. A missing diff, a definition that has no fingerprint yet, and an incomplete dependency list each trigger this fallback.
- Known limitation. A change reached through a relationship — an interface's description, an owner's name — regenerates every member of every affected definition rather than only the members affected. No artifact is left stale, because this regenerates more than is needed rather than less, but artifacts that render relationship data benefit less.
- Known limitation. A composite artifact that includes another artifact's content stays stale after a merge.
Selective regeneration is controlled by selective_execution_after_merge (INFRAHUB_SELECTIVE_EXECUTION_AFTER_MERGE) and is enabled by default. Set it to false to restore full regeneration on every merge.
Re-run only the Generators a commit affected
Commit to a linked repository and, within a Proposed Change, only the Generators your commit affected re-run — those whose source file, GraphQL query, or definition changed. Correcting a typo in an unrelated README no longer re-runs every Generator across every member of its target group.
- 1.10 introduced this precise regeneration for artifacts; it now covers Generators as well.
- Each decision to run or skip is recorded in the Proposed Change's task log, naming the file, query, or definition field responsible.
- Read-only repositories get the same behavior, even on branches where
sync_with_gitis disabled. - Generators imported before this upgrade keep working unchanged and adopt the precise behavior on their next import. Until then they re-run on any file change in their repository, so no output is left stale during the transition.
- Known limitation. Editing
.infrahub.ymlstill re-runs everything in that repository.
Infrahub cannot detect every dependency automatically — a helper module imported at runtime from a sibling package, for example. Declare those files with the optional watch: key on generator_definitions in .infrahub.yml:
generator_definitions:
- name: interface_generator
file_path: "generators/interfaces.py"
class_name: InterfaceGenerator
targets: network-devices
query: device_interfaces
watch:
files:
- "generators/shared/" # directory entries are recursive
- "generators/helpers/naming.py"Recompute computed attributes only when their inputs change
Commit to a linked repository, or change the schema, and only the computed attributes that change can reach are recomputed. Each of those previously caused a full recompute.
- A commit to a linked repository previously recomputed every Transformation-based computed attribute in the instance, for every object of its kind. Now only the attributes whose Transformation changed are recomputed, so an edit and its exact revert trigger no recompute.
- A schema change previously recomputed every computed attribute on the branch. A computed attribute is now recomputed only when the change affects a schema element its value depends on, including elements reached through a relationship. Where the impact cannot be determined, a full recompute still runs.
Both rely on a new fingerprint attribute on the definitions that produce output from a repository: GraphQL queries, transformations, artifact definitions, and Generator definitions. It holds a content hash of the definition's inputs, and it is branch-aware, so a change is detected the same way whether it arrived by a Git import, a merge, a rebase, or a direct edit.
Python Transformations need watch:; Jinja2 Transformations no longer do. A fingerprint is stable only when Infrahub can resolve every file the Transformation depends on. When it cannot, it adds the commit id to the fingerprint, so the Transformation recomputes on every commit to its repository.
- For a Python Transformation, Infrahub detects only the Transformation's own package directory, so an import from anywhere else needs an explicit
watch:list. An emptywatch:list opts in. - For a Jinja2 Transformation, Infrahub parses the template's
include/import/extendsgraph, so a fully resolved template gets a stable fingerprint without a declaration. The emptywatch: {}that 1.10 required is no longer needed. A template with an unresolvable include still recomputes on every commit.
The first import of a Transformation after upgrading recomputes its attributes once. This happens once, not on every commit.
python_transforms:
- name: cabling_plan
class_name: CablingPlan
file_path: "./transforms/cabling_plan.py"
# Infrahub cannot detect this import from the Transformation's own directory,
# so declaring it here completes the dependency list.
watch:
files:
- src/infrahub_solution_ai_dc/protocols.pyLearn more: Declaring extra dependencies with watch.
Reduce recompute time after a large merge or rebase
Merge or rebase a branch and the computed attributes, display labels, and human-friendly IDs on the affected nodes recompute in one combined pass. Each changed node previously produced its own recompute job, so a merge across many nodes created many small tasks. The resulting values are identical.
On the reference dataset used during development, a large post-merge recomputation went from about 1,500 background tasks to two, and from about 275 seconds to about one second. Results will vary with the dataset, schema, and automation definitions in each environment.
- Recomputed values are written in bulk. Each value previously took its own update task and its own API call; results are now saved together.
- For a computed attribute backed by a Python Transformation, the Transformation's Git repository is initialized once per batch instead of once per object.
- An object whose recomputed value has not changed is skipped, so it is neither written nor recomputed again.
- Known limitation. The recompute runs in one task but is not yet narrowed. For a computed attribute backed by a Python Transformation it still recomputes every node of that attribute's kind rather than only the nodes the merge affected. Restricting it to the affected nodes is the next step.
Validate only the constraints a change can violate
Open a Proposed Change, merge, or rebase, and only the constraints that change could break are validated. A branch that changed only data no longer runs every validator in the schema.
- Only the kinds the change affected are validated, plus the generics they inherit from and any kind whose uniqueness constraint reads an attribute of a changed kind.
- Within a kind, only the fields a constraint applies to are checked. Changing an attribute that belongs to no uniqueness constraint no longer re-validates that kind's uniqueness, and re-parenting a child no longer runs the children check on the parent.
A uniqueness scan that could not complete on a large dataset now finishes, and a schema diff between two identical branches returns empty.
What this does not cover
The changes above run fewer regenerations and recomputes. None of them makes an individual regeneration or recompute faster.
- A real change still regenerates every artifact that depends on it. Editing a Transformation, artifact definition, or Generator regenerates every artifact it produces, and this prerelease does not make that regeneration faster.
- Merge, rebase, and diff are unchanged. This prerelease changes what happens after a merge, not the time it takes to compute and apply the diff.
- Schema load is unchanged. Computed-attribute recompute and constraint validation are narrowed, but the time to process the schema itself is not. An unrelated schema addition still takes the same time regardless of graph size.
The limitations of each individual change are noted with that change above.
Task and API priority
Interactive operations and background processing previously shared the same task queue and competed for the same API capacity. This prerelease separates them at both levels, so an operation someone is waiting for starts without waiting for the backlog to clear.
Run interactive actions ahead of background work
Start a merge while the instance works through a backlog, and it now runs ahead of that backlog instead of queueing behind it. Infrahub classifies tasks across three priority queues.
- High — branch operations (create, merge, rebase, delete, validate), Proposed Change merges, Generator definition runs, schema load and check, Transformation rendering, and on-demand artifact generation.
- Medium — IPAM reconciliation.
- Low — processing whose result nobody is waiting for: profile refresh, and post-merge follow-ups such as Proposed Change cancellation, automatic branch deletion, and artifact and Generator regeneration. These previously ran at the same high priority as the merge that started them.
A sub-task started by a high-priority operation runs at the same priority, so the priority applies through an entire chain of tasks. The queues are created on startup, so no migration is needed.
Keep the UI responsive when the instance is busy
Keep using the web UI while heavy background processing runs. Because the API previously could not distinguish a UI request from background traffic, a busy instance could stop serving the UI.
- A request declares its priority with the
X-Priorityheader (high,medium, orlow; a missing or invalid value is treated asmedium). The web UI sendshighon its own calls andlowon background calls that opt in. - Under sustained overload, lower-priority requests are rejected first, returning
429 Too Many Requestswith aRetry-Afterheader before the request does any work. - Low-priority requests are rejected before medium ones, and high-priority requests are protected until the database is under extreme load.
An initial data load, or a deliberate full regeneration, now goes through this back-off as well. That protects the instance under peak load, but can make the full run take longer.
On a normally loaded deployment, no requests are rejected. Metrics are published on /metrics, and the whole behavior can be turned off with INFRAHUB_API_BACKPRESSURE_ENABLED=false.
Merge protection and recovery
A merge interrupted by a stopped worker can now be recovered, and a reordered list no longer blocks a merge.
Recover from a failed merge
Recover a merge whose worker stopped partway through, using one command. The instance was previously left with a half-merged default branch and a branch stuck in MERGING, and restoring a backup or running database queries manually was the only option. That state is now detectable, visible, and recoverable.
- Writes are blocked during a merge. Writes to both the default branch and the source branch are refused while a merge runs, and a new merge or rebase is refused while one is in progress. A blocked write receives an error marked as temporary, asking the caller to retry shortly. The block is removed automatically when the merge finishes or is rolled back.
- A stalled merge is detected. A merge whose worker is no longer running is recorded as a failed branch, and the default branch stays protected. Writes then receive a distinct, non-retryable error telling the operator that recovery is required.
infrahub recover mergerestores the previous state. It rolls back the partial merge on the default branch, resets the branch and any associated Proposed Change toOPEN, and removes the write protection. It shows what it will do and asks for confirmation (--yesto skip), and it is safe to run twice. Object, attribute, and relationship timestamps are restored to their pre-merge values, including for objects affected by a schema migration.
Branch-status rejections now include structured GraphQL error codes — BRANCH_ALREADY_MERGED, BRANCH_NEEDS_REBASE, and MERGE_IN_PROGRESS — so API and SDK clients can react to a code instead of matching message text.
Merge branches that reordered the same list
Set the new ordered flag to false on a List or JSON-array attribute so reordering its elements is no longer reported as a conflict during a merge or rebase. Adding or removing an element is still a conflict.
The built-in enum, dropdown choices, used_by, and restricted_namespaces attributes now use this. That resolves a case where two branches held the same set of dropdown choices in a different order, and the branch could not be rebased.
Inspect, retry and cancel webhook deliveries
Open any webhook delivery and see the request Infrahub sent, the response it received, and the number of attempts made. Every delivery is now its own task, visible in the Tasks tab and from the webhook's related-tasks panel.
- Readable failures. An expected delivery failure — an unreachable target, a TLS problem, a timeout, an HTTP error from the receiver, a misconfiguration — is reported as a named reason with a hint on what to check, instead of a raw Python stack trace. Unexpected errors keep their stack trace, so you can still distinguish a defect in Infrahub from a delivery failure.
- Automatic retry. A failed delivery retries with a delay between attempts. Retries stop early for failures that cannot succeed on a retry, such as a
4xxresponse or an invalid configuration. - Retry a delivery that has finished. Retrying resends the payload captured when the event occurred, against the webhook's current configuration, so correcting a wrong URL, header, or signing key and then retrying works as expected. The original delivery is kept as a record.
- Cancel a delivery that is still running. Cancelling stops its remaining attempts.
Schema and data modeling
Store an address without a prefix, and see which fields a schema load does not apply.
Store a bare IP address with the IPAddress kind
Use the new IPAddress attribute kind for a value that is an address and nothing else. Where IPHost normalizes 192.0.2.1 to 192.0.2.1/32, an IPAddress value must not include a prefix length or netmask, and is rejected if it does. DNS records, NTP and syslog targets, monitoring targets, and ACL entries therefore hold the address you entered, with no prefix appended.
IPv6 values are normalized to their compressed lowercase form. Values sort lexically rather than numerically.
Normalize values before changing an attribute's kind
Normalize an attribute's values before converting it to IPHost, IPNetwork, IPAddress, or MacAddress. A conversion is now refused when the existing values are not already stored in the form the new kind requires.
Converting a Text attribute holding aa-bb-cc-dd-ee-ff to MacAddress is rejected, because MacAddress stores AA:BB:CC:DD:EE:FF.
See which fields a schema load does not apply
Submit a schema and see which fields Infrahub did not apply, instead of having them ignored silently. POST /api/schema/load now validates every submitted node, generic, and extension against a published write contract, and reports what it did not apply:
- A field Infrahub computes and owns —
inherited,used_by,hierarchy, and similar — is accepted, dropped, and reported as a warning naming every element that included it. Reading a schema back from Infrahub, editing it, and loading it again keeps working. - An unrecognized field name is an error that names the field and its path.
- An attribute parameter belonging to a different attribute kind, such as
start_rangeon aNumberattribute, is now rejected. Earlier versions accepted it and discarded it silently.
infrahubctl schema load and infrahubctl schema check print the warnings, and infrahubctl validate schema reports them offline. The write contract is published as a model in the Python SDK, so a payload can be checked before it is submitted.
UI improvements
Sort and filter large lists from the UI, and choose the date format you read timestamps in.
Sort object lists from the UI
Sort an object list from a column header or from the toolbar, using the backend ordering support added in 1.10. Both controls read the sort from the page URL, so they always agree.
- From a column header. Clicking a header opens a menu with "Sort ascending", "Sort descending", and "Filter". A column that points at a single related object offers a "Sort by" entry listing that object's sortable attributes. The header shows the active direction; selecting that direction again returns to the default order. Per-column filtering is now the "Filter" item in this menu.
- From the toolbar. A Sort control beside the Filter control opens a list of sort entries you can add, reorder by dragging, and remove. Dragging changes which field takes precedence. The control shows a count when a sort is active.
A sorted view can be bookmarked and shared. Sorting runs on the server, so it stays fast on large lists. This works in object lists and in the IPAM IP address and prefix lists.
Choose the date and time format for the UI
Choose the date format and timezone you read timestamps in. Dates previously followed the browser's locale, and an organization could not set a default of its own.
- Set your own date format and timezone from a Preferences card on your account Profile tab. The setting applies on every device you sign in from.
- Set organization-wide defaults for every user on the Global preferences tab, if you hold the new
manage_global_preferencespermission. - A field you leave unset inherits the organization default, and uses the browser's setting when no default exists. Personal preferences are private: reading or writing them affects only your own record.
Also in the UI
- Sort the Proposed Changes list by any sortable field. It defaults to newest created first.
- A branch's details page shows whether you are working on that branch, and offers a one-click switch when you are not.
- The default branch is identified by the flag the API returns rather than by the name
main, which reported the wrong branch whenINFRAHUB_INITIAL_DEFAULT_BRANCHwas set. - Lists show the current data after a write, instead of a deleted row or a stale value until the page was reloaded.
- Relationship selectors honor the
common_parentschema property, offering only peers that share the parent selected elsewhere in the same form. - Hierarchical relationships show the related kind's label — "Region" or "Site" — in place of "Parent" and "Children".
- Adding a child to a hierarchical object pre-fills the parent field with the object you started from.
- Markdown artifacts render Mermaid diagrams from fenced mermaid code blocks.
- The branch "Sync with Git" flag explains that it controls whether an Infrahub-created branch is propagated to Git, not whether the branch came from Git.
Delete a repository together with the objects it owns
Delete a repository and the objects it owns are deleted with it. This previously failed. A repository imports and generates objects — Transformations, checks, GraphQL queries, Generators, and the artifact definitions, artifacts, Generator instances, and validators that depend on them. Mandatory relationships attach those objects to the repository, and Infrahub refuses to break a mandatory relationship, so the only way to remove a repository was to delete each of those objects manually, in dependency order.
- The deletion is still refused, with an error naming the object, if one of those objects is required by something outside the repository, so a partial deletion cannot leave orphaned data.
- Validators attached to Proposed Changes, and the artifacts and Generator instances they produced, are removed too. That is deliberate: the repository owns those objects.
Minor changes
Performance
- GraphQL queries that request only the
idof a cardinality-one relationship's peer no longer build the full peer node. - Diff node field summaries are retrieved in pages bounded by
database.query_size_limit, so a very large diff no longer risks exhausting the Neo4j heap during merge and rebase validation.
Reliability
- Merging or rebasing a branch that deletes a node refreshes the derived values of the nodes that read it across a relationship, so their computed attributes, display labels, and human-friendly IDs no longer name a deleted object.
- Creating a node no longer fails when a Jinja2 computed attribute formats a value taken from a number pool.
- Jinja2 transformations are no longer reported as updated on every repository import when their content has not changed.
- Git repository synchronization no longer stops when a branch that was already merged still exists on the remote.
- Removing a relationship from a schema closes the underlying relationship data, so stale peers no longer reappear if a relationship with the same identifier is added again later.
- A flow run waiting for an automatic retry is no longer marked as crashed too early.
- A TLS certificate verification failure against an external endpoint, such as a webhook target or an SSO provider, is reported as a TLS error rather than a generic connection error.
Telemetry
- The daily anonymous telemetry payload adds adoption and activity signals: active accounts and account groups, open non-system branches, two node counts that respect branches and time, and a summary of the previous full UTC day. Each field is collected independently, and reporting remains opt-out through
INFRAHUB_TELEMETRY_OPTOUT.
Dependencies
- The frontend GraphQL transport moved from
@apollo/clientto the lighter@urql/core, reducing the JavaScript bundle size with no change in behavior. - The Infrahub container image is smaller: the build toolchain is now in a build stage excluded from the runtime image, and
numpyandpyarroware no longer installed by default.pyarrowremains available through the object-transfer extra forinfrahubctl object load.
Breaking changes
Read this section before installing this prerelease. These are the same breaking changes planned for the 1.11.0 GA release, but since this is a beta, treat them as subject to change until GA ships.
Artifacts are deleted when their target leaves the target group
Artifact generation now deletes artifacts whose target object is no longer a member of the artifact definition's target group. Those artifacts were previously kept indefinitely as stale copies — for example after merging a branch that removed the target from the group.
If any workflow reads those leftover artifacts, capture their content before the target is removed from the group. The deletion happens on the next full generation pass over the definition: after a merge, after a definition update, or on a call to the generate endpoint with no node filter.
A related fix limits this cleanup to passes that examined every member, so a generation run narrowed to specific members no longer deletes artifacts it did not examine.
The infrahub git-agent command has been removed
The deprecated infrahub git-agent command has been removed. The task worker replaced it several releases ago. If any script or deployment still calls it, move that call to the task worker before upgrading.
OpenAPI component schemas are renamed
GET /api/schema returns the same response body as before, but its OpenAPI component schemas are renamed to NodeSchemaRead, GenericSchemaRead, ProfileSchemaRead, and TemplateSchemaRead (from APINodeSchema, APIGenericSchema, APIProfileSchema, and APITemplateSchema). If you generate client types from openapi.json, update those type names and regenerate.
Upgrade notes
Runtime versions
If: you run your own Neo4j rather than the version shipped with Infrahub.
Then: plan the database upgrade to 2026.05.0 alongside this upgrade. The container image ships Neo4j 2026.05.0, up from 2025.10.1, and Python 3.14, up from 3.13.
Python Transformations and watch:
If: you use Python transformations that import modules from outside their own package directory.
Then: declare those files with the watch: key on python_transforms entries in .infrahub.yml. An empty watch: list opts in. Without it, Infrahub adds the commit id to the Transformation's fingerprint, and the Transformation recomputes its computed attributes on every commit to its repository. Jinja2 Transformations no longer need watch: — see Recompute computed attributes only when their inputs change.
Notes: the first import of a Transformation after upgrading recomputes its attributes once. This happens once, not on every commit.
Attribute kind conversions
If: you convert an attribute into IPHost, IPNetwork, IPAddress, or MacAddress.
Then: normalize the existing values to the form the new kind stores first. A conversion is now refused when the stored values are not already normalized.
Installing this prerelease
Because 1.11.0b1 is a beta, install it on a staging or test instance, not on production, and use a backup you're comfortable restoring from if something goes wrong.
Before you install this prerelease, we strongly advise you to delete branches that are no longer needed within Infrahub. Deleting old branches helps speed up the upgrade process and avoids running migrations for branches that are no longer needed.
Please read the Breaking changes section above before starting.
Please make sure to upgrade any existing installations of the infrahub-sdk to vTODO.
Please make sure to back up your instance of Infrahub and make sure you are familiar with and have tested the restore procedure. For more information visit https://docs.infrahub.app/backup
First, stop the existing Infrahub instance.
docker compose downSecond, update the Infrahub version running in your environment.
- For deployments via Docker Compose, download the updated Docker Compose file
curl https://infrahub.opsmill.io -o docker-compose.yml
- Set the
VERSIONenvironment variable and start the environmentexport VERSION="1.11.0b1"; docker compose pull && docker compose up -d
- For deployments via Kubernetes, use the latest prerelease version of the Helm chart supplied with this build.
Third, once you have the desired version of Infrahub in your environment, run the migrations.
docker compose exec infrahub-server infrahub upgradeFinally, restart all instances of Infrahub.
docker compose restartFull changelog
Added
- Added a
selective_execution_after_mergesetting (envINFRAHUB_SELECTIVE_EXECUTION_AFTER_MERGE) that narrows post-merge regeneration to the artifact and Generator definitions the merge actually affected, instead of regenerating every definition for every member. When enabled, a merge captures its diff and dispatches only the definitions whose query, definition, or code inputs changed, and only for the affected members. Every uncertain signal falls back to full regeneration, so no affected artifact or Generator can be left stale. On a merge that runs a Generator, the artifacts built from that Generator's output are regenerated after the Generator completes. The setting is enabled by default. (#10033) CoreGraphQLQuery,CoreTransformation,CoreArtifactDefinition, andCoreGeneratorDefinitionnow include an optional, branch-awarefingerprintattribute holding a content hash of the definition's inputs. A null value means the node predates the feature or has not been re-imported since; nothing is backfilled.- Added the ability to request a specific prefix length when allocating from an IP address or IP prefix pool. (#9631)
- A branch's details page now shows whether you are working on that branch, and lets you switch to it. (#10111)
- Added a new
IPAddressattribute kind that stores a bare IP address, rejecting any value that includes a prefix length or netmask. IPv6 values are normalized to their compressed lowercase form. Values sort lexically rather than numerically. (#10090) - The daily anonymous telemetry payload now reports additional adoption and activity signals, including active accounts and account groups, the count of open non-system branches, node counts that respect branches and time, and an
activity_24hsummary of the previous full UTC day. All changes are additive; each field is reported independently, so a single failing source returnsnullfor that field. (#9805) - Added a Sort picker to the Proposed Changes list to order it by any sortable field. The list now defaults to newest created first. (#9915)
- Webhook deliveries now each run as their own observable task, with automatic retry, a named failure reason, a captured request and response, and operator retry and cancel controls.
- Writes to the default branch and to the source branch are now blocked for the full duration of a branch merge, and a new merge or rebase is refused while a merge is in progress. Blocked writes receive an error marked as temporary, and the protection is removed automatically once the merge completes or is rolled back.
- Added the
infrahub recover mergeCLI command to recover from a failed branch merge. It rolls back the partial merge on the default branch, resets the branch and any associated Proposed Change toOPEN, and removes the write protection. The command is operator-confirmed (--yesto skip) and idempotent. - Branch-status write rejections now include structured GraphQL error codes:
BRANCH_ALREADY_MERGED,BRANCH_NEEDS_REBASE, andMERGE_IN_PROGRESS(HTTP423). - Priority-aware API backpressure. The API accepts an optional
X-Priorityrequest header (high,medium, orlow; defaults tomedium). Under sustained overload the admission layer rejects lower-priority traffic first, returning429 Too Many Requestswith aRetry-Afterheader. Prometheus metric families are published on/metrics, and the layer can be turned off withINFRAHUB_API_BACKPRESSURE_ENABLED=false. - The frontend declares request priority on every API call via the
X-Priorityheader, sendinghighby default andlowfor background calls that opt in. - Added a database-stress signal derived from the reference permission query, and used it to make API request rejection progressively tiered, with new Prometheus gauges and
INFRAHUB_API_BACKPRESSURE_*settings to tune the window, warm-up sample count, per-class thresholds, and per-class caps. - Added user and global preferences as internal
StandardNodeobjects. A singlePreferencemodel holds both layers: one row per user for that user's overrides, and a separate row for organization-wide defaults (date_format,timezone). TheInfrahubEffectivePreferencesGraphQL query returns the merged effective values for the calling user. - Added a personal Preferences card to the account Profile tab for date format and timezone, a Global preferences tab for administrators, and the
manage_global_preferencesglobal permission that governs the organization-wide row. - Removing a relationship from a schema now closes the relationship data using that schema instead of leaving it active but unreachable in the graph. (#2474)
- Markdown artifacts now render Mermaid diagrams from fenced mermaid code blocks.
- Added an input style variant to the Button component and adopted it for selector triggers so they match the styling of form inputs.
Changed
- Breaking: artifact generation now deletes artifacts whose target is no longer a member of the artifact definition's target group. Any workflow that relied on reading those leftover artifacts must capture their content before the target is removed. (#9790)
- Allocating from an IP address or prefix pool with a conflicting prefix length now returns a clear error instead of silently reusing the existing reservation. (#9631)
- The fingerprint commit-id fold is now builder-aware, so a Jinja2 Transformation whose dependencies are fully resolved produces a stable fingerprint without an explicit
watch:declaration. Python Transformations and Generators are unchanged — Infrahub detects only their package directory, so awatch:declaration is still required to omit the commit id. (#10096) - Changing an attribute's kind is now rejected when the existing values are not already stored in the form the new kind requires. This affects conversions into
IPHost,IPNetwork,IPAddress, andMacAddress. (#10090) POST /api/schema/loadnow validates every submitted node, generic, and extension against a user-facing write contract, and reports the fields it does not apply instead of ignoring them. The write contract is published as a committed model in the Python SDK.GET /api/schemaOpenAPI component schemas are renamed toNodeSchemaRead,GenericSchemaRead,ProfileSchemaRead, andTemplateSchemaRead. (#10095)- When a Proposed Change includes commits to a linked repository, Infrahub now re-runs only the Generators whose source, GraphQL query, or definition was actually affected by the change, and records each run-or-skip decision in the Proposed Change's task log. Extra dependencies can be declared with the optional
watch:key ongenerator_definitionsentries in.infrahub.yml. - When a Git commit changes a Python Transformation, Infrahub now recomputes only the computed attributes whose Transformation actually changed, instead of recomputing every Transformation-based computed attribute on any commit.
- Merging or rebasing a branch now runs a single combined recompute for computed attributes, display labels, and human-friendly ids instead of one recompute job per changed node, and saves the results in bulk. A node whose recomputed value has not changed is skipped. The recompute runs as one task but is not yet narrowed: for a Python-Transformation computed attribute it still covers every node of that attribute's kind. (#10034)
- Improved the performance of GraphQL queries that request only the
idof a cardinality-one relationship's peer. (#10062) - Diff node field summaries are now retrieved in pages bounded by
database.query_size_limitinstead of a single aggregating query. (#10106) - Tasks a user is waiting on now run at high priority; profile refresh and post-merge follow-ups run at low priority, with IPAM reconciliation at medium.
- Column headers in object lists and IPAM IP address and prefix lists now open a menu to sort the list from the column, and per-column filtering moves into that menu.
- Hierarchical parent and children relationships now display the related kind's label instead of the generic "Parent" and "Children" everywhere they appear.
- Added an explanation to the branch "Sync with Git" flag clarifying that it controls whether an Infrahub-created branch is propagated to Git. (#9883)
- Flow runs that stop sending heartbeats are marked as crashed only after a longer grace period.
- Upgraded Python to 3.14 (from 3.13). Upgraded Neo4j to 2026.05.0 (from 2025.10.1).
Fixed
- Branches containing only data changes no longer run every validator across every kind in the schema. Schema diffs between identical branches now return empty. (#2592)
- Schema constraint validation triggered by a data change now runs only the node-level constraints whose specific field or path was actually modified. (#10019)
- Computed-attribute recompute is now narrowed to the schema elements a change actually affects, including elements reached through relationships. (#9415)
- Added an
orderedflag to attribute schemas. When set tofalseon aListor JSON-array attribute, reordering its elements is no longer reported as a conflict during merge and rebase. The built-inenum, dropdownchoices,used_by, andrestricted_namespacesattributes now use this. (#9764) - Merging or rebasing a branch that deletes a node now refreshes the derived values of the nodes that read the deleted node across a relationship. (#9845)
- Fixed node creation failing when a Jinja2 computed attribute formatted a value taken from a number pool. (#7836)
- Fixed Jinja2 Transformations always being marked as updated during repository imports even though there were no changes. (#3094)
- Fixed git repository synchronization stopping when a branch that had been merged still existed on the remote. (#9931)
POST /api/schema/loadnow returns the warnings it collected even when the submitted schema matches the one already loaded. (#10095)- Fixed relationship selectors in object forms not honoring the
common_parentschema property. (#10039) - Fixed the frontend identifying the default branch by the literal name
mainrather than by theis_defaultflag the API returns. (#10129) - Fixed concurrent GraphQL calls from the frontend sharing a single in-flight request and receiving each other's responses. Every call now gets its own request. (#10136)
- Artifact generation no longer deletes artifacts that a narrowed run did not examine; the stale-artifact cleanup now runs only for a pass that examined every member.
- Artifact and Generator regeneration during a Proposed Change no longer fails when a definition references a repository that has no changes in the branch diff.
- Selective regeneration no longer skips an artifact or Generator when the change affects a node the definition's query reads through a relationship, and now narrows Generator instances to the members actually affected.
- Fixed display labels and human-friendly ids that read across a relationship not refreshing when they were recomputed by their own id.
- Rolling back a failed branch merge now fully restores
updated_atandupdated_bymetadata, including for objects affected by a schema migration, and a recovery interrupted partway through can be re-run cleanly. - Webhook task runs can now be found from the webhook related-tasks panel.
- A TLS certificate verification failure when Infrahub connects to an external HTTPS endpoint is now reported as a TLS error instead of a generic connection error.
- Fixed some GraphQL requests returning an unexpected HTTP 500 error instead of a node-not-found (404) response. (#9926)
- When adding a child to a hierarchical object, the creation form now pre-fills the parent field with that object.
- Fixed the focus ring on text inputs being clipped on the left and right edges when an object form is opened inside a sheet.
Removed
- Removed the
infrahub git-agentcommand line utility, which was deprecated several releases ago and replaced by the task worker. (#5584)
Housekeeping
- Reduced the size of the Infrahub container image: the build toolchain is now in a dedicated build stage excluded from the runtime image, and
numpyandpyarroware no longer installed by default (pyarrowremains available via the object-transfer extra forinfrahubctl object load). - Replaced the frontend GraphQL transport (
@apollo/client) with the lighter@urql/core, preserving all request behavior. (#10059) - Restructured the frontend tooling around a pnpm workspace with one shared lock file, a shared catalog for cross-package versions, and BuildKit cache mounts in the node build stages.
- Introduced a shared
isRelationshipSchematype guard in the frontend schema entity so attribute and relationship discrimination is defined in one tested place. - Made the Neo4j Bolt connector thread-pool ceiling tunable in the testcontainers stacks via
INFRAHUB_TESTING_DB_BOLT_THREAD_POOL_MAX_SIZE.