Hatchling Error Handling & Validation Reference
Overview
This comprehensive reference is designed to help you assist users with Hatchling build issues. It documents error handling, validation mechanisms, and resolution strategies in Hatchling, the modern Python packaging build backend. Use this reference when helping users understand common errors, validation rules, and best practices for robust package building.
Documentation Structure
Core Error Categories
-
- Force-include path existence validation
- Path normalization and case sensitivity
- URI formatting and space escaping
- Symlink resolution in dev mode
-
- "At least one file selection option must be defined" error
- File selection options (packages, include, only-include)
- Default heuristics and when they fail
- Bypass selection for metadata-only wheels
-
- PEP 440 version format validation
- Standard version scheme and bumping
- Version epoch handling
- Dynamic version configuration
-
- SPDX expression validation
- LicenseRef custom identifiers
- PEP 639 compliance
- License file configuration
-
- Metadata version 2.1-2.4 compatibility
- Field mapping across versions
- PEP 517/660 compliance
- Backward compatibility strategies
-
- Default detection mechanisms
- Common heuristic failures
- Package name normalization
- Namespace package detection
-
- Build hook validation
- Artifact validation
- Metadata field validation
- Output content validation
Quick Error Resolution Guide
Common Errors and Quick Fixes
| Error | Quick Fix | Documentation |
|---|---|---|
At least one file selection option must be defined |
Add packages = ["src/mypackage"] |
Wheel File Selection |
Force-included path does not exist |
Ensure path exists or remove from config | Path Validation |
Invalid version: x.y.z |
Use PEP 440 format: 1.0.0 |
Version Validation |
Unknown license: [id] |
Use SPDX identifier or LicenseRef- |
SPDX Validation |
Invalid classifier |
Check against PyPI classifiers | Build Validation |
Version Compatibility Matrix
| Hatchling | Python | Metadata | Key Features |
|---|---|---|---|
| 1.27.0+ | 3.8+ | 2.4 | Latest license fields |
| 1.26.0+ | 3.8+ | 2.3 | Any LicenseRef- pattern |
| 1.22.0+ | 3.8+ | 2.2 | Dependencies method |
| 1.19.0+ | 3.8+ | 2.1 | Path validation, file selection |
| 1.18.0+ | 3.8+ | 2.1 | Dropped Python 3.7 |
Essential Configuration Examples
Minimal Working Configuration
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "1.0.0"
description = "A simple package"
license = "MIT"
requires-python = ">=3.8"
[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]
Comprehensive Error-Preventing Configuration
[build-system]
requires = ["hatchling>=1.19.0"]
build-backend = "hatchling.build"
[project]
name = "robust-package"
dynamic = ["version"]
description = "Package with comprehensive validation"
license = "MIT OR Apache-2.0"
license-files = ["LICENSE*"]
requires-python = ">=3.8"
dependencies = [
"requests>=2.28.0",
"click>=8.0.0"
]
[tool.hatch.version]
path = "src/robust_package/__about__.py"
scheme = "standard"
validate-bump = true
[tool.hatch.build.targets.wheel]
packages = ["src/robust_package"]
exclude = ["**/__pycache__", "**/*.pyc"]
[tool.hatch.build.targets.wheel.force-include]
"README.md" = "robust_package/README.md"
[tool.hatch.metadata]
allow-direct-references = false
Validation Scripts
Pre-Build Validation
#!/usr/bin/env python3
"""validate_project.py - Run before building."""
import sys
from pathlib import Path
import tomllib
def validate_all():
"""Run all validations."""
errors = []
# Load config
with open("pyproject.toml", "rb") as f:
config = tomllib.load(f)
# Check required fields
project = config.get("project", {})
if not project.get("name"):
errors.append("Missing project.name")
# Check build config
wheel = (config.get("tool", {})
.get("hatch", {})
.get("build", {})
.get("targets", {})
.get("wheel", {}))
if not any([wheel.get(k) for k in
["packages", "include", "only-include", "bypass-selection"]]):
errors.append("No file selection configured")
# Check paths exist
for package in wheel.get("packages", []):
if not Path(package).exists():
errors.append(f"Package directory not found: {package}")
if errors:
print("Validation errors found:")
for error in errors:
print(f" ✗ {error}")
sys.exit(1)
print("✓ All validations passed")
if __name__ == "__main__":
validate_all()
Migration Guides
From setuptools to Hatchling
# setup.py (old)
from setuptools import setup, find_packages
setup(
name="my-package",
version="1.0.0",
packages=find_packages(where="src"),
package_dir={"": "src"},
install_requires=["requests>=2.28.0"],
license="MIT",
)
# pyproject.toml (new)
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "1.0.0"
dependencies = ["requests>=2.28.0"]
license = "MIT"
[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]
Best Practices Summary
- Always specify file selection explicitly for wheels
- Use PEP 440 version formats
- Validate paths before building
- Use SPDX identifiers for licenses
- Test builds in CI/CD
- Pin Hatchling version for stability
- Document non-standard layouts
- Automate validation checks
Troubleshooting Workflow
graph TD
A[Build Error] --> B{Error Type?}
B --> C[File Selection]
B --> D[Path Missing]
B --> E[Version Invalid]
B --> F[License Invalid]
C --> G[Add packages/include/only-include]
D --> H[Check paths exist]
E --> I[Use PEP 440 format]
F --> J[Use SPDX or LicenseRef-]
G --> K[Test Build]
H --> K
I --> K
J --> K
K --> L{Success?}
L -->|Yes| M[Deploy]
L -->|No| A
Additional Resources
Official Documentation
- Hatch Documentation
- Python Packaging Guide
- PEP 517 - Build System Interface
- PEP 621 - Project Metadata
- PEP 639 - License Metadata
Specifications
- Core Metadata Specifications
- SPDX License List
- PEP 440 - Version Identification
Tools
- validate-pyproject - Validation tool
- twine - Package validation and upload
- check-wheel-contents - Wheel validation
Contributing
To contribute to this documentation:
- Follow the existing format and structure
- Include version information for features
- Provide working code examples
- Test all examples with current Hatchling
- Update the index when adding new documents
Version
This documentation is current as of Hatchling v1.27.0 (November 2024).
License
This documentation is provided under the same license as the parent project.