From 8ba55264a985b435dfaa3730311e1ac4d0818521 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Tue, 23 Jun 2026 12:26:06 +0100 Subject: [PATCH 1/2] test(pkg): repro @doc-new crash on locked META-only lib (#15290) Build @doc-new against a lock-dir package whose lib is exposed via a META file only (no dune-package) and observe the as_outside_build_dir_exn crash in Odoc_new.modules_of_dir. Signed-off-by: Ali Caglayan --- .../test-cases/pkg/doc-new-with-locked-lib.t | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t diff --git a/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t b/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t new file mode 100644 index 00000000000..623a79234c3 --- /dev/null +++ b/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t @@ -0,0 +1,53 @@ +Reproduction for https://github.com/ocaml/dune/issues/15290 + +Building @doc-new with package management enabled crashes when a locked +package installs a library via a META file (without a dune-package), because +the odoc rules classify it as a "fallback" directory and try to read the +cmti directory as if it were outside the build tree. + + $ mkdir external_sources + + $ cat >external_sources/META < version = "0.0.1" + > description = "" + > archive(byte) = "fakefmt.cma" + > EOF + + $ touch external_sources/fakefmt.cma + + $ cat >external_sources/fakefmt.install < lib: [ + > "META" + > "fakefmt.cma" + > ] + > EOF + + $ make_dune_project 3.25 + + $ cat > dune-workspace < (lang dune 3.25) + > (pkg enabled) + > EOF + + $ make_lockdir + $ make_lockpkg fakefmt < (version 0.0.1) + > (source (copy $PWD/external_sources)) + > EOF + + $ cat > dune-project < (lang dune 3.25) + > (package (name foo) (depends fakefmt)) + > EOF + + $ cat > dune < (library + > (public_name foo) + > (libraries fakefmt)) + > EOF + + $ touch foo.ml + + $ dune build @doc-new 2>&1 | grep "Internal error" + Internal error! Please report to https://github.com/ocaml/dune/issues, + [1] From 0c83f2cfc1e34583bc63b8b89b2fcfcf707c0830 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Tue, 23 Jun 2026 12:33:02 +0100 Subject: [PATCH 2/2] fix(odoc): handle build-dir cmti paths in @doc-new fallback (#15290) [Odoc_new.modules_of_dir] called [Fs_memo.dir_contents] via [Path.as_outside_build_dir_exn], which crashes when the cmti directory lives under [_build/_private/.../target/lib] - the case for libraries installed by lock-dir packages. Use [Fs.dir_contents] instead: it branches on build-vs-outside and waits on [Build_system.build_dir] for inside-build paths, so the locked package's install action finishes before we list its modules. Signed-off-by: Ali Caglayan --- src/dune_rules/odoc/odoc_new.ml | 5 ++--- .../test-cases/pkg/doc-new-with-locked-lib.t | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dune_rules/odoc/odoc_new.ml b/src/dune_rules/odoc/odoc_new.ml index 04b4ed61403..98774e65537 100644 --- a/src/dune_rules/odoc/odoc_new.ml +++ b/src/dune_rules/odoc/odoc_new.ml @@ -1178,11 +1178,10 @@ let modules_of_dir d : (Module_name.t * (Path.t * [ `Cmti | `Cmt | `Cmi ])) list List.find_map extensions ~f:(fun (ext', ty) -> Option.some_if (Filename.Extension.equal ext ext') ty) in - Fs_memo.dir_contents (Path.as_outside_build_dir_exn d) + Fs.dir_contents d >>| function | Error _ -> [] - | Ok dc -> - let list = Fs_memo.Dir_contents.to_list dc in + | Ok list -> List.filter_map list ~f:(fun (x, ty) -> match ty, Filename.extension x |> Filename.Extension.Or_empty.extension with | Unix.S_REG, Some ext when Option.is_some (ty_of_ext ext) -> diff --git a/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t b/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t index 623a79234c3..1f3e8f73499 100644 --- a/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t +++ b/test/blackbox-tests/test-cases/pkg/doc-new-with-locked-lib.t @@ -48,6 +48,8 @@ cmti directory as if it were outside the build tree. $ touch foo.ml - $ dune build @doc-new 2>&1 | grep "Internal error" - Internal error! Please report to https://github.com/ocaml/dune/issues, - [1] + $ dune build @doc-new + File "fakefmt.mld", line 7, characters 0-11: + Warning: '{!modules ...}' should not be empty. + File "page-fakefmt.odoc": + Warning: Failed to lookup child page dummy