Skip to content
Latchkey

setuptools "Multiple top-level packages discovered in a flat-layout" in CI

setuptools >= 61 auto-discovers packages. In a flat layout (packages at the repo root) it found several top-level directories that look like packages (often your package plus tests or docs) and refuses to guess which belong in the distribution.

What this error means

A setuptools build stops with "error: Multiple top-level packages discovered in a flat-layout" and lists the directories it found, such as your package alongside tests and docs.

setuptools
error: Multiple top-level packages discovered in a flat-layout: ['mypkg', 'tests', 'docs'].

To avoid accidental inclusion of unwanted files or directories,
setuptools will not proceed with this build.

Common causes

Several root directories look like packages

With a flat layout, tests/ and docs/ sit beside your package at the root. Auto-discovery cannot tell which is the real distribution, so it stops.

No explicit package configuration

Without [tool.setuptools.packages] or find directives, setuptools falls back to auto-discovery, which is deliberately conservative about ambiguity.

How to fix it

Declare packages explicitly with find

  1. Add a [tool.setuptools.packages.find] table.
  2. Use include to name your package and exclude to drop tests/docs.
  3. Re-run the build.
pyproject.toml
[tool.setuptools.packages.find]
include = ["mypkg*"]
exclude = ["tests*", "docs*"]

Adopt a src layout

Move your package under src/ so the root has a single discoverable tree and tests/docs no longer collide with discovery.

pyproject.toml
[tool.setuptools.packages.find]
where = ["src"]

How to prevent it

  • Configure packages explicitly instead of relying on auto-discovery.
  • Use a src layout to isolate the shipped package from tests and docs.
  • Build the sdist and wheel in CI to catch discovery ambiguity early.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →