## Changelog 2026

Note:

 Get notified by watching releases for git repositories: lamindb,
  laminhub-public, laminr, nf-lamin, and bionty. For other years, see:
  2025 · 2024 · 2023 · 2022

# 2026-02-09 db 2.1.2

UX:

* 🚸 Broaden curation to dtypes that are unions PR @Zethson

* 🚸 More debug logging in case instance creation on hub fails due to
  quota exceeded PR @Koncopd

Performance:

* ⚡️ Download large single files from s3 with "boto3" by default in
  "artifact.cache()" PR @Koncopd

Bug fixes:

* 🐛 Fix initializing an instance with a cloud storage and the db
  parameter passed PR @Koncopd

# 2026-02-09 hub 1.14.0

* 🚸 Better experience saving markdown notes PR @chaichontat

* 🐛 Fix text overflow for sheet names on "Launch" page PR
  @chaichontat

* 🐛 Fix the count & filtering for recreated artifacts in the run
  input/output panes PR @sunnyosun

* 🐛 More robust error handling for account handle suggestions PR
  @chaichontat

* 🐛 Properly show a 404 response for artifacts when non-existent PR
  @chaichontat

* 💄 Polish the "Overview" page PR @ninhja01 @chaichontat

* 💄 Display run params PR @falexwolf

* 💄 Add the story to the About page PR @falexwolf @chaichontat

# 2026-02-02 db 2.1.1

UX:

* 🚸 Better detection of read-only connections for write errors and
  tracking PR @Koncopd

* 🚸 A "lamin settings cache-dir reset" CLI command for resetting the
  cache directory to the default path PR @Koncopd

* 🚸 A "S3QueryPath.is_bucket_versioned()" method to check if the
  bucket in an s3 path is versioned PR @Koncopd

Bug fixes:

* 🐛 Fix edge case in Django reset during "ln.setup.init(...)" PR
  @Koncopd

# 2026-02-03 nf 0.5.0

This release revamps the configuration ("nextflow.config") for more
control over which artifacts are registered and which metadata is
attached ("kind", "projects", "ulabels"). Here is an example Nextflow
config:

 lamin {
 instance = "laminlabs/lamindata"
 api_key = secrets.LAMIN_API_KEY
 output_artifacts {
 rules {
 output {
 pattern = ".*"
 order = 1
 type = "include"
 project_uids = ["AbCdEfGhIjKl"]
 ulabel_uids = ["AbCd0123"]
 }
 // don't publish state.yaml files
 yaml {
 pattern = ".*\\.state\\.yaml"
 type = "exclude"
 order = 10
 }
 }
 }
 }

New functionality:

* ✨ Control which files are registered as artifacts using pattern-
  based rules PR @rcannood

* ✨ Link projects and ulabels to transforms, runs, and artifacts with
  new "run" and "transform" config sections for granular control PR
  @rcannood

* ✨ New "api" section for connection settings replaces root-level
  fields PR @rcannood

UX:

* 🚸 Better mapping of HTTP error codes from the LaminDB API PR
  @rcannood

Bug fixes:

* 🐛 Fixed edge case in tracking input files and improved S3 path
  rendering PR @rcannood

Deprecations: The following API components are now deprecated and are
scheduled for removal in v0.6

| --- | --- | --- |
| Type | Deprecated | Replacement |
| =================================== | =================================== | =================================== |
| Config | "project" | "project_uids" |
| --- | --- | --- |
| Config | "supabase_api_url", | "api { ... }" section |
| "supabase_anon_key", |
| "max_retries", "retry_delay" |
| --- | --- | --- |
| Function | "getArtifactFromUid()" | "file('lamin://owner/instance/ar |
| tifact/uid')" |
| --- | --- | --- |

# 2026-02-02 db 2.1.0 | bionty 2.1.0

MLOps:

* 🚸 Overhaul the pytorch "lightning" integration PR @Zethson
  @jorenretel

Notebooks, scripts, workflows:

* 🚸 Recognize packaged python source code across "track()",
  "@flow()", and "@step()" PR @falexwolf

* 🚸 Default to creating a global run context in "ln.flow()" PR
  @falexwolf

* 🚸 Serialize "Path", "UPath", and handle "None" in transform
  "params" PR @falexwolf

* 🚸 Reflect user CLI calls in transform description PR @falexwolf

* 🚸 Improve error message for running a script or notebook outside
  the development directory PR @falexwolf

Validation:

* 🚸 Unify validating features with and without the presence of a
  schema, fix parsing ISO-format strings as datetime if mapped on a
  feature with "dtype=str" PR @falexwolf

CLI:

* 🚸 Delete records via CLI PR @falexwolf

* 🚸 Better error behavior in "lamin save" when transform is on a
  different branch PR @sunnyosun

General UX:

* 🚸 Enable convenient re-upload of local file after upload failure PR
  @falexwolf

* 🚸 Return information about deleted objects rather than "None" upon
  hard delete PR @falexwolf

* 🚸 Introduce safe-guards in updating the space of artifacts PR
  @Koncopd

* 🚸 Switch on SQL logging if "ln.settings.verbosity" is ""debug"" PR
  @sunnyosun

* 🚸 Raise canonical "InstanceNotFoundError" in "Registry.connect()"
  PR @falexwolf

* 🚸 Allow users to pass ids of foreign keys in "Artifact()"
  constructor PR @Koncopd

* 🚸 Check local path existence on "artifact.save()" PR @Koncopd

Performance:

* ⚡️ Much faster permanent run & transform deletion PR @falexwolf

* ⚡️ 1 sec speed-up for basic CLI calls through optimized
  "lamindb_setup" import time PR @falexwolf

Ontology updates in "bionty":

* 🚸 Default the "CellLine" source to "cellosaurus" PR @sunnyosun

* 🚸 More robust "add_source" PR @sunnyosun

* 🚸 Allow users to set "bionty" root dir via "BIONTY_ROOT_DIR" env
  variable PR @Koncopd

* 🍱 New ontology version: Gene, release-114 PR PR @sunnyosun @Zethson

* 🍱 New ontology version: Gene, release-113 PR @sunnyosun

* 🍱 New ontology version: Organism PR @sunnyosun

* 🍱 Update standard ontologies PR @sunnyosun

Better conventions in CLI (backward compatible):

* 🚚 Support "key"-based deletion in "lamin delete" PR @falexwolf

* 🚚 "lamin cache" is now "lamin settings cache-dir", refactor
  settings managemennt PR @falexwolf

* 🚚 More consistent "lamin switch" and "lamin create" commands PR
  @falexwolf

The "wetlab" plugin was renamed to "pertdb" (backward compatible):

* 🚚 Rename "wetlab" to "pertdb" PR @falexwolf

Bugs:

* 🐛 Refactor & fix feature-based queries for records PR @falexwolf

* 🐛 Fix PyYAML serialization of NotebookNode PR @Zethson

* 🐛 Fix "Artifact.from_dataframe()" to support path input PR @Zethson

* 🐛 Fix "standardize()" ignoring passed source PR @Zethson

Docs:

* 📝 Convert guides to markdown format PR @falexwolf

* 📝 Legible API reference for "lamindb.models" PR @falexwolf

* 📝 Consistent reference to Python/R alternative for all CLI
  commands, expand "lamin annotate" PR @falexwolf

* 📝 Document backward relationships and add "RelatedManager[T]" to
  "ManyToMany" type annotations PR PR @falexwolf

* 📝 README improvements PR @falexwolf

Refactoring:

* ♻️ Rather flag "_storage_ongoing" than "_storage_completed" PR
  @falexwolf

* ♻️ Efficiently encode uploading information PR @falexwolf

* ♻️ Fully leverage "Context" to manage the run context of function
  executions PR @falexwolf

* ♻️ Use publishable LaminHub key PR @Koncopd

* ♻️ Remove internal "use_proxy_db" option PR @Koncopd

# 2026-01-31 hub 1.13.0

* ⚡ Update JWT signing from HS256 to ES256 for better performance PR
  @fredericenard

* 💄 Display output and input records on run detail page PR @falexwolf

# 2026-01-27 hub 1.12.1

* 🐛 Fix an issue in the Seqera Launch connector PR @chaichontat

# 2026-01-26 hub 1.12.0

* ✨ Configurable default Seqera workspace and compute environment PR
  @chaichontat

* ✨ Two new endpoints to help users authenticate and interact with
  instances through the API PR @fredericenard

* 🐛 Fix attaching a space to an instance in case an org admin isn't a
  collaborator of that space PR @fredericenard

* 🐛 Prevent empty results when searching Artifacts PR @chaichontat

* 💄 Landing page: re-format taglines and update schematic PR
  @chaichontat

# 2026-01-21 nf 0.4.0

✨ This release allows for the automatic tracking of input artifacts
by discovering their remote URIs, using functionality implemented in
Nextflow 25.10. Hence, it requires Nextflow >=25.10.0 PR @rcannood

 export NXF_VER=25.10.2
 nextflow run <pipeline> \
 --input "https://raw.githubusercontent.com/..." \
 -with-report report.html

# 2026-01-20 hub 1.11.0

* ✨ Beta: A Logs page with "DbWrite" events PR - frontend:
  @chaichontat backend: @Koncopd

* ✨ Support children type in record registration PR @chaichontat

* 🚸 Handle suggestions when adding users PR @chaichontat

* 🐛 Fix run metadata selection state PR @chaichontat

* 💄 Show records on the overview page PR @falexwolf

# 2026-01-14 hub 1.10.0

* ✨ Add "/artifacts/by-path" endpoint PR @fredericenard

* 🐛 Write run annotations on the Launch page into the "RunRecord"
  registry PR @falexwolf

* 📝 Improve landing page - metadata and lakehouse sections PR
  @falexwolf

# 2026-01-13 hub 1.9.1

* 🐛 More strictly enforce schema during UI-based record creation PR
  @chaichontat

* 🐛 Broaden database server access permissions to include shared
  database servers PR @fredericenard

* 📝 Improve landing page - introduce tags and improve language PR
  @falexwolf

# 2026-01-13 R 1.2.2

* ⬆️ Update minimal "lamindb" version to 2.0.0 PR @falexwolf PR
  @lazappi

# 2026-01-12 nf 0.3.0

* ✨ Implement "FileSystem" for "lamin://" URIs PR @rcannood

* ⬆️ Bump "lamindb" to v2 PR @falexwolf

* 🚸 Update formatting of "source_code" when a new transform is
  created PR @rcannood

* 📝 Add version compatibility table PR @rcannood

# 2026-01-12 hub 1.9.0

* ✨ Transform search bar also understands run names and UIDs PR
  @chaichontat

* 🚸 Default to not listing inferred schemas without names PR
  @chaichontat

* 🐛 Fix the broken "New schema" button on the records page due to
  "lamindb" v2 PR @chaichontat

* 🐛 Fix the broken pipeline "Launch" button due to "lamindb" v2 PR
  @sunnyosun

# 2026-01-11 db 2.0.1

* 🚸 Backward compatibility for querying features by "dtype" PR
  @falexwolf

# 2026-01-11 db 2.0.0

This release makes the database schema fully consistent and thereby
improves UX, integrity, and enables long-term stability.

-[ ⚠️ With the exception of previous deprecations, your code continues
to run as is, but you will receive new warnings about renamed API
components. ]-

Main changes:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| Function tracking | "@ln.tracked()" | "@ln.flow()", | ✓ |
| "@ln.step()" |
| --- | --- | --- | --- |
| "Feature" field | "dtype" | "_dtype_str" | ✓ |
| --- | --- | --- | --- |
| "Schema" field | "n" | "n_members" | ✓ |
| --- | --- | --- | --- |
| "IsVersioned" field | "version" | "version_tag" | ✓ |
| --- | --- | --- | --- |
| "Transform" field | "type" | "kind" | ✓ |
| --- | --- | --- | --- |
| "Artifact" field | "feature_sets" | "schemas" | ✓ |
| --- | --- | --- | --- |
| "Feature" field | "coerce_dtype" | "coerce" | ✓ |
| --- | --- | --- | --- |
| "Schema" field | "coerce_dtype" | "coerce" | ✓ |
| --- | --- | --- | --- |
| "FeatureValue" registry | "FeatureValue" | "JsonValue" | ✓ |
| --- | --- | --- | --- |

Private fields that are now public:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "Artifact" field | "_subsequent_runs" | "recreating_runs" | ✗ |
| --- | --- | --- | --- |
| "Artifact" field | "_feature_values" | "json_values" | ✗ |
| --- | --- | --- | --- |
| "Run" field | "_recreated_artifacts" | "recreated_artifacts" | ✗ |
| --- | --- | --- | --- |
| "SQLRecord" field | "_branch_code" (only on | "branch_id" | ✗ |
| DB-level) |
| --- | --- | --- | --- |

Changes to auxiliary (JSON) fields:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "Run" field | "cli_args" (in "_aux") | "cli_args" ("CharField(m | ✓ |
| ax_length=1024)") |
| --- | --- | --- | --- |
| "Feature" field | "default_value" (in | "default_value" | ✓ |
| "_aux") | ("JSONField") |
| --- | --- | --- | --- |
| "Feature" field | "nullable" (in "_aux") | "nullable" | ✓ |
| ("BooleanField") |
| --- | --- | --- | --- |
| "Schema" field | "flexible" (in "_aux") | "flexible" | ✓ |
| ("BooleanField") |
| --- | --- | --- | --- |
| "Artifact" field | "_is_saved_to_storage_lo | "_save_completed" (in | ✗ |
| cation" (in "_aux") | "_aux") |
| --- | --- | --- | --- |

On link models with labels:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "IsLink" model | "feature_ref_is_name" | removed | ✗ |
| --- | --- | --- | --- |
| "IsLink" model | "label_ref_is_name" | removed | ✗ |
| --- | --- | --- | --- |

For completeness, changes in recently introduced unused API
components:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "RootBlock" registry | "RootBlock" | "Block" | ✗ |
| --- | --- | --- | --- |
| "Block" field | "context" | "key" | ✗ |
| --- | --- | --- | --- |
| "BaseBlock" field | "type" | "kind" | ✗ |
| --- | --- | --- | --- |
| "Run" field | "_logfile" | removed | ✗ |
| --- | --- | --- | --- |
| "Transform" field | "config" | removed | ✗ |
| --- | --- | --- | --- |
| "Transform" field | "flow" | removed | ✗ |
| --- | --- | --- | --- |
| "Transform" field | "is_flow" | removed | ✗ |
| --- | --- | --- | --- |
| "Transform" field | "_template" | removed | ✗ |
| --- | --- | --- | --- |

Changes in the "bionty" and "wetlab" modules:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "BioRecord" registry | "uid" (X chars) | "uid" (14 chars) | "*" ".get()" of the X |
| chars uid continues to |
| work |
| --- | --- | --- | --- |

"*" uids are re-encoded to 14 chars with the first X chars conserved.

Changes in the "wetlab" module:

| --- | --- | --- | --- |
| What | Before | After | Backward compatible |
| =========================== | =========================== | =========================== | =========================== |
| "Experiment" registry | "Experiment" | removed | ✗ |
| --- | --- | --- | --- |
| "BioSample" registry | "BioSample" | removed | ✗ |
| --- | --- | --- | --- |
| "TechSample" registry | "TechSample" | removed | ✗ |
| --- | --- | --- | --- |
| "Donor" registry | "Donor" | removed | ✗ |
| --- | --- | --- | --- |
| "Well" registry | "Well" | removed | ✗ |
| --- | --- | --- | --- |
| "GeneticPerturbation" | "system" | "type" | ✗ |
| field |
| --- | --- | --- | --- |
| "CompoundPerturbation" | "targets" | removed | ✗ |
| field |
| --- | --- | --- | --- |
| "Compound" field |  | "targets" | ✓ |
| --- | --- | --- | --- |

If you have data in removed registries you'll see a warning that your
data gets exported to parquet files. You can import these parquet
files into the "Record" registry under an "Experiment" type without
losing of functionality.

-[ ⚠️ After migrating databases to v2 via "lamin migrate deploy"
"lamindb" package installations with v1 will raise errors. This is the
last planned database migration that breaks older clients. ]-

All instances connected to LaminHub have been migrated and there is no
need to act.

If you are an admin of a self-managed instance, please migrate your
database with "lamin migrate deploy".

For details see the Compatibility Matrix and the source code.

-[ ⚠️ For "laminr" and "nf-lamin" users ]-

For "laminr" users with an *auto-managed reticulate environment*,
please run this:

 reticulate::py_require("lamindb>=2.0.1") # DO THIS FIRST
 ln <- laminr::import_module("lamindb")

For "nf-lamin" users, please upgrade to "0.3.0".

Removals:

* 🔥 Remove deprecated v1 API components PR @falexwolf

Features:

* ✨ Track shell scripts PR @falexwolf

* ✨ Enable managing workflows by decorating functions with
  "@ln.flow()" and "@ln.step()" and deprecate "@ln.tracked()" PR
  @falexwolf

Architecture:

* 🏗️ For more robustness and to convey the field's special nature in
  the API and the database schema, replace "Feature.dtype" with
  "Feature._dtype_str" to now hold a serialization that links object
  types ("Record" + "ULabel") based on their "uid" instead of their
  "name" and type hierarchy PR @falexwolf

UX:

* 🚸 Add "feature.dtype_as_object" PR @sunnyosun

* 🚸 Add "description" argument to "Transform.from_git()" PR
  @falexwolf

* 🚸 Allow passing "_key_is_virtual" on "Artifact" creation PR
  @Koncopd

* 🚸 Raise "SystemExit" upon "InstanceNotFound" only from CLI PR
  @falexwolf

* 🚸 Raise error for init or import issues in "lamin io snapshot" PR
  @Zethson

* 🚸 Do not track inputs when calling "collection.artifacts.all()" PR
  @Koncopd

* 🚸 Raise a clear error if calling "CanCurate" and similar registry
  class methods on objects PR @falexwolf

* 🚸 Sort features in "describe()" PR @falexwolf

Database-level changes:

* 🗃️ Rename "RootBlock" to "Block" with a column "key" akin to
  "Artifact" and "Transform" PR @falexwolf

* 🗃️ Refactor "_storage_completed" mechanism and remove unique
  constraints on type names PR @falexwolf

* 🗃️ Migrate most auxiliary fields to SQL columns PR @falexwolf

* 🗃️ Simplify "Transform" PR @falexwolf

* 🗃️ Rename "IsVersioned.version" to "IsVersioned.version_tag",
  "Transform.type" to "Transform.kind", "FeatureValue" to "JsonValue",
  "BaseBlock.type" to "BaseBlock.kind", delete "Transform._template"
  and "Run._logfile" PR @falexwolf

* 🗃️ Rename "Artifact._subsequent_runs" to "Artifact.recreating_runs"
  and "Run._recreated_artifacts" to "Run.recreated_artifacts" PR
  @falexwolf

* 🗃️ Rename "SQLRecord._branch_code" to "SQLRecord.branch_id" and
  remove "feature_ref_is_name" and "label_ref_is_name" fields from
  link models PR @falexwolf

* 🗃️ Rename "Artifact.feature_sets" to "Artifact.schemas" PR
  @falexwolf

* 🗃️ Migrate the "Feature" and "Schema" database tables to LaminDB v2
  PR @falexwolf

* 🗃️ Swap accessor names for "SchemaComponent" links, consistent
  "ManyToMany" field names for "RecordRecord" links PR @falexwolf

* 🗃️ Better names for the "ManyToMany" fields for the annotating runs
  and artifacts of an "Artifact" PR @falexwolf

Bug fixes:

* 🐛 Account for size 0 environments PR @falexwolf

Bionty:

* 🎨 Re-encode BioRecord uid to 14 chars PR @sunnyosun

* 🗃️ Migrations for bionty v2 PR @sunnyosun

* ♻️ Refactor require_organism PR @sunnyosun

* 🗃️ Migrations for LaminDB v2 PR @falexwolf

* 🔥 Remove deprecated "display_available_sources" PR @falexwolf

Wetlab:

* 🗃️ Migrations for wetlab v2 PR @sunnyosun

* 🗃️ Migrations for LaminDB v2 PR @falexwolf

* 🗃️ Create a composite index for "artifact", "perturbationtarget"
  fields in "ArtifactPerturbationTarget" PR @Koncopd

* 🗃️ Create a composite index for "artifact", "geneticperturbation"
  fields in "ArtifactGeneticPerturbation" PR @Koncopd

Docs:

* 📝 Improve the "Space" document PR @falexwolf

* 📝 Improve the "Artifact.replace()" docs PR @falexwolf

* 📝 Improve FAQ doc on trashing and archiving PR @falexwolf

* 📝 Render return type annotations of "Artifact.open()" in docs PR
  @falexwolf

Config:

* 🔧 Introduce "InstanceSettings.is_managed_by_hub" PR @falexwolf

* 🔧 Rename "zarr" extra to "zarr_v2" PR @Koncopd

* 🔧 Add ".vitessce.json" to loaders PR @namsaraeva

Refactoring:

* ♻️ Refactor "require_organism" PR @sunnyosun

* ♻️ Better re-use Django's "ObjectDoesNotExist" and
  "MultipleObjectsReturned" PR @falexwolf

* ♻️ Return file size in "hash_file()" PR @falexwolf

* ♻️ Squash migrations and re-build SQLite init database PR @falexwolf

* ♻️ More verbose migration integrity check PR @falexwolf

* ♻️ Call "lamin migrate deploy" even if initializing from pre-built
  sqlite file PR @falexwolf

Dependencies:

* ⬆️ Bump "fsspec" packages upper bound PR @Koncopd

* ⬆️ Bump "anndata" upper bound PR @Koncopd

* ⬆️ Set the correct lower bound for "websockets" PR @Koncopd

# 2026-01-11 hub 1.8.0

* 🐛 Fix special character handling in filters PR @chaichontat

* 🐛 Fix filtering state leakage across different pages PR
  @chaichontat

* 🐛 Fix feature hover card not functioning correctly PR @chaichontat

# 2026-01-03 hub 1.7.0

* 🚸 Infinite scroll for transform list PR @chaichontat

* 📝 Update data validation video PR @namsaraeva

* 📝 Improve language on landing page PR @falexwolf