Packing fails when using a separate metadata.yaml file and `--project-dir` argument
Metadata
Current evaluation
Fixed by PR #2644 (c87eca0d), which loads separate metadata.yaml from the correct project directory. The fix was slated for Charmcraft 4.2.1.
Resolution: closed resolved
Reason: PR #2644, commit c87eca0d, corrected metadata lookup when packing through --project-dir. Maintainer @lengau confirmed on April 9, 2026 that the fix would ship in 4.2.1.
Evaluated by: mr-cal-bot
No scores available.
Issue body
### Check existing issues
- [x] I've verified that this bug isn't described by any existing issues.
### Bug description
<!-- Describe the bug, including any relevant context or screenshots. -->
I don't see an exact match for this bug, but it certainly seems like it might be related to https://github.com/canonical/charmcraft/issues/1809.
A charm defined using the old system with a separate `metadata.yaml` file can build without error when built from within the directory containing the `charmcraft.yaml` and `metadata.yaml` file but will error when built outside that directory using the `--project-dir` flag.
It results in validation errors such as the following:
```
$ charmcraft pack --project-dir ./charm
charmcraft internal error: 3 validation errors for PlatformCharm
name
Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
summary
Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
description
Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
```
### Steps to reproduce
<!-- Provide step-by-step instructions to reproduce the bug. -->
I can confirm this happens with a K8s charm. It may also happen with machine charm, which I have not yet tried.
1. Create a new charm with `charmcraft init --profile kubernetes` inside a directory called `charm`
2. Move the following fields from `charmcraft.yaml` to a new `metadata.yaml` file
* `name`
* `title`
* `summary`
* `containers`
* `resources`
3. It may not matter, but I also deleted some fields from the `charmcraft.yaml`, such that it was left with only the following
* `type`
* `base`
* `platforms`
* `parts`
4. (Optional) From within the charm directory, run `charmcraft pack` - this should succeed. Delete the charm afterwards.
5. Move up a directory with `cd ..`
6. Now try `charmcraft pack --project-dir ./charm`. This should fail
### Environment
<!-- We need to understand the context in which Charmcraft failed. Please let us know if you are running Charmcraft in destructive mode, whether you are using LXD or Multipass, and which operating system you are running Charmcraft on. -->
I am using Ubuntu 24.04. Charmcraft is using LXD to build.
### charmcraft.yaml
```yaml
<!-- If the issue is specific to a project, share its `charmcraft.yaml`. This field automatically renders as YAML, so you don't need to add special formatting. -->
```
### Log output
```shell
2025-11-27 15:14:29.415 Starting charmcraft, version 4.0.1
2025-11-27 15:14:29.415 Log verbosity level set to BRIEF
2025-11-27 15:14:29.417 Preparing application...
2025-11-27 15:14:29.417 Setting up ConfigService
2025-11-27 15:14:29.434 Configuring application...
2025-11-27 15:14:29.434 Getting runtime directory.
2025-11-27 15:14:29.434 Using '/run/user/1738809480/3700465' for the state directory.
2025-11-27 15:14:29.434 Setting up StateService
2025-11-27 15:14:29.434 Setting 'charmcraft.started_at' to '2025-11-27T15:14:29.434239'.
2025-11-27 15:14:29.434 Loading state file '/run/user/1738809480/3700465/charmcraft.yaml'.
2025-11-27 15:14:29.434 State file doesn't exist.
2025-11-27 15:14:29.434 Writing state to '/run/user/1738809480/3700465/charmcraft.yaml'.
2025-11-27 15:14:29.434 Set 'charmcraft.started_at' to '2025-11-27T15:14:29.434239'.
2025-11-27 15:14:29.435 Configuring application...
2025-11-27 15:14:29.435 Setting 'charmcraft.started_at' to '2025-11-27T15:14:29.435183'.
2025-11-27 15:14:29.435 Loading state file '/run/user/1738809480/3700465/charmcraft.yaml'.
2025-11-27 15:14:29.435 Overwriting existing value.
2025-11-27 15:14:29.435 Writing state to '/run/user/1738809480/3700465/charmcraft.yaml'.
2025-11-27 15:14:29.435 Set 'charmcraft.started_at' to '2025-11-27T15:14:29.435183'.
2025-11-27 15:14:29.465 Build plan: platform=None, build_for=None
2025-11-27 15:14:29.466 Setting up ProjectService
2025-11-27 15:14:29.466 Loading project file '/home/william.taylor@canonical.com/charm/charmcraft.yaml
2025-11-27 15:14:29.467 Running charmcraft pack on host
2025-11-27 15:14:29.467 Using parallel build count of 16 from CPU count
2025-11-27 15:14:29.467 Checking if 'version' exists.
2025-11-27 15:14:29.467 Getting value for 'version'.
2025-11-27 15:14:29.467 Got None (updated=False) for 'version'.
2025-11-27 15:14:29.467 'version' exists.
2025-11-27 15:14:29.467 Getting value for 'version'.
2025-11-27 15:14:29.467 Got None (updated=False) for 'version'.
2025-11-27 15:14:29.467 Processing grammar (on amd64 for amd64)
2025-11-27 15:14:29.467 Processing grammar for plugin: uv
2025-11-27 15:14:29.467 Processing grammar for source: .
2025-11-27 15:14:29.467 Processing grammar for build-snaps: ['astral-uv']
2025-11-27 15:14:29.468 charmcraft internal error: 3 validation errors for PlatformCharm
2025-11-27 15:14:29.468 name
2025-11-27 15:14:29.468 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.468 For further information visit https://errors.pydantic.dev/2.11/v/missing
2025-11-27 15:14:29.468 summary
2025-11-27 15:14:29.468 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.468 For further information visit https://errors.pydantic.dev/2.11/v/missing
2025-11-27 15:14:29.468 description
2025-11-27 15:14:29.468 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.468 For further information visit https://errors.pydantic.dev/2.11/v/missing
2025-11-27 15:14:29.472 Traceback (most recent call last):
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_application/application.py", line 663, in run
2025-11-27 15:14:29.472 return_code = self._run_inner()
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/charmcraft/application/main.py", line 143, in _run_inner
2025-11-27 15:14:29.472 return super()._run_inner()
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_application/application.py", line 640, in _run_inner
2025-11-27 15:14:29.472 return_code = dispatcher.run() or os.EX_OK
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_cli/dispatcher.py", line 564, in run
2025-11-27 15:14:29.472 return self._loaded_command.run(self._parsed_command_args)
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_application/commands/base.py", line 200, in run
2025-11-27 15:14:29.472 result = self._run(parsed_args, **kwargs) or result
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/charmcraft/application/commands/lifecycle.py", line 163, in _run
2025-11-27 15:14:29.472 project = cast(models.CharmcraftProject, self._services.get("project").get())
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_application/services/project.py", line 608, in get
2025-11-27 15:14:29.472 self._project_model = self.render_for(
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/craft_application/services/project.py", line 553, in render_for
2025-11-27 15:14:29.472 project_model = self._app.ProjectClass.from_yaml_data(
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/charmcraft/models/project.py", line 260, in from_yaml_data
2025-11-27 15:14:29.472 return cls.unmarshal(data)
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/charmcraft/models/project.py", line 246, in unmarshal
2025-11-27 15:14:29.472 return PlatformCharm.unmarshal(data)
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/charmcraft/models/project.py", line 241, in unmarshal
2025-11-27 15:14:29.472 return cls.model_validate(data)
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.472 File "/snap/charmcraft/7517/lib/python3.12/site-packages/pydantic/main.py", line 705, in model_validate
2025-11-27 15:14:29.472 return cls.__pydantic_validator__.validate_python(
2025-11-27 15:14:29.472 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-11-27 15:14:29.473 pydantic_core._pydantic_core.ValidationError: 3 validation errors for PlatformCharm
2025-11-27 15:14:29.473 name
2025-11-27 15:14:29.473 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.473 For further information visit https://errors.pydantic.dev/2.11/v/missing
2025-11-27 15:14:29.473 summary
2025-11-27 15:14:29.473 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.473 For further information visit https://errors.pydantic.dev/2.11/v/missing
2025-11-27 15:14:29.473 description
2025-11-27 15:14:29.473 Field required [type=missing, input_value={'type': 'charm', 'base':...snaps': ['astral-uv']}}}, input_type=dict]
2025-11-27 15:14:29.473 For further information visit https://errors.pydantic.dev/2.11/v/missing
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Fixed by PR #2644 (c87eca0d), which loads separate metadata.yaml from the correct project directory. The fix was slated for Charmcraft 4.2.1. | |
| stealth/space-bunny-alpha | — | closed resolved | Fixed in merged PR #2644 (c87eca0d), which made metadata lookup honor --project-dir; the maintainer confirmed it would ship in 4.2.1. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Fixed validation errors when packing charms with a separate metadata.yaml file using the --project-dir flag. The fix is included in version 4.2.1. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed a bug causing validation errors when running charmcraft pack with --project-dir and a separate metadata.yaml file. The resolution will be released in version 4.2.1. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed a bug where charmcraft pack failed with validation errors when using --project-dir with a separate metadata.yaml file. The fix will be included in version 4.2.1. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Fixed a bug where charmcraft pack failed with validation errors when using --project-dir with a separate metadata.yaml. The fix will be included in version 4.2.1. |
Update history
No update history recorded yet.
Related work
-
Likely Fixed By:
canonical/charmcraft#2644
(confidence 99%)
Commit c87eca0d fixes metadata loading to use the actual project directory.
-
Related To:
canonical/charmcraft#2694
(confidence 90%)
Follow-up spread-test change exercising metadata handling through pack --project-dir.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #2498 fix: `charmcraft pack --project-dir` with metadata.yaml | charmcraft | closed | Closed unmerged; superseded by #2644, which fixed metadata lookup for --project-dir and shipped in Charmcraft 4.2.1. | |
| #1809 --project-dir fails to find metadata.yaml when running in destructive mode | charmcraft | open | Destructive pack with --project-dir and split metadata.yaml was a path-resolution bug; later lifecycle fixes and the documented Charmcraft 4.2.1 fix for analogous #2493 resolve it. | |
| #821 5.5.0 changes pack semantics if the project file has different metadata | craft-application | open | Metadata-only charmcraft.yaml edits were skipped as "Already packed," leaving stale .charm artifacts; Charmcraft PR #2890 is reported to fix repacking after the edit. | |
| #2890 feat: skip repacking if project is not changed | charmcraft | merged | Merged PR implementing metadata mediation for config.yaml and actions.yaml so charmcraft skips repacking unchanged projects; fixes #2858 and canonical/craft-application#821. | |
| #2694 test(different-dir-metadata): use pack --project-dir instead of pull | charmcraft | merged | Merged PR #2694 (commit dd684338) fixed the failing different-dir-metadata spread test by switching `charmcraft pull` to `charmcraft pack --verbose --project-dir=charm`, plus output and restore checks. | |
| #2672 fix: use `charmcraft pack` instead of `charmcraft pull` in different-dir-metadata spread test | charmcraft | closed | Closed unmerged: the charmcraft pull -> pack fix for the different-dir-metadata spread test was superseded by PR #2694, merged as commit dd684338 using `charmcraft pack --verbose --project-dir=charm` plus output/restore checks. |