fix(preprocess): report empty metadata.yaml clearly
Metadata
Current evaluation
Adds a check for empty metadata.yaml files to provide clearer error messages. Addresses issue #2071. PR is clean, tests updated, CI failures unrelated, awaiting maintainer review.
Suggested action: needs review
Reason: The PR is a small, focused fix (+19/-1 lines) that improves error messaging for empty metadata.yaml files, addressing issue #2071. It includes tests, release notes, and the author has addressed all concerns and confirmed CI failures are unrelated. The PR has 0 reviewers and is awaiting maintainer review.
Evaluated by: mr-cal-bot
Impact:
30
Quick Win:
22
Complexity:
10
Confidence:
85
Actionability:
80
Issue body
Fixes #2071
When `metadata.yaml` is empty, packing a charm now says the file is empty instead of claiming it breaks the Juju specification.
**What this code is for**
`add_metadata` in `charmcraft/preprocess.py` runs when Charmcraft loads a project, before `charmcraft pack` and other commands. If a `metadata.yaml` sits next to `charmcraft.yaml`, it reads that file with `util.safe_yaml_load` and copies its fields into the project data.
**Before this PR**
A charm author has a valid `charmcraft.yaml` and a leftover `metadata.yaml` that holds only a license comment, then runs `charmcraft pack`.
1. `add_metadata` finds `metadata.yaml` and loads it with `util.safe_yaml_load`.
2. A file with no content, or only comments, loads as `None`.
3. `None` is not a `dict`, so the `if not isinstance(metadata_yaml, dict)` check raises.
4. The author sees `Invalid file: 'metadata.yaml'` with `Ensure metadata.yaml meets the juju metadata.yaml specification.`
5. The author goes looking for a schema mistake in a file that has nothing in it.
**After this PR**
Same author, same command.
1. Same as above through step 2.
2. A new `if metadata_yaml is None` check runs first and raises `Empty file: 'metadata.yaml'`.
3. The author sees `Add the charm metadata to metadata.yaml or delete the file.` and knows what to do.
4. A `metadata.yaml` that holds a list or a plain string still gets `Invalid file: 'metadata.yaml'`, as before.
**The diagram**
```mermaid
flowchart LR
classDef box fill:#eef1ff,stroke:#4c5bd4,color:#111827
classDef bad fill:#ffd6d6,stroke:#cc0000,color:#111827,stroke-width:3px
classDef good fill:#c8f0c8,stroke:#008800,color:#111827,stroke-width:3px
subgraph BEFORE["BEFORE: empty file reported as invalid"]
direction TB
B1["charmcraft pack"] --> B2["add_metadata"]
B2 --> B3["util.safe_yaml_load returns None"]
B3 --> B4{"not isinstance dict"}
B4 -->|"None is not a dict"| B5["Invalid file: 'metadata.yaml'"]
B4 -->|"mapping"| B6["fields copied into project"]
end
subgraph AFTER["AFTER: empty file reported as empty"]
direction TB
A1["charmcraft pack"] --> A2["add_metadata"]
A2 --> A3["util.safe_yaml_load returns None"]
A3 --> A4{"THE CHANGE: metadata_yaml is None"}
A4 -->|"empty or only comments"| A5["Empty file: 'metadata.yaml'"]
A4 -->|"mapping"| A6["fields copied into project"]
end
B1 ~~~ A1
class B1,B2,B3,B6 box
class A1,A2,A3,A6 box
class B4,B5 bad
class A4,A5 good
linkStyle 3 stroke:#cc0000,stroke-width:5px
linkStyle 8 stroke:#008800,stroke-width:5px
style BEFORE fill:#fff5f5,stroke:#cc0000,color:#111827
style AFTER fill:#f3fff3,stroke:#008800,color:#111827
```
**The change**
`add_metadata` gets an `if metadata_yaml is None` check before the existing `isinstance` check. It raises `CraftValidationError` with the message `Empty file: 'metadata.yaml'`, a resolution telling the author to fill or delete the file, the same docs link, and the same exit code 65. `tests/unit/test_preprocess.py` now expects the new message for an empty file and a comment only file, and keeps a case for a list that still gets `Invalid file`. The 4.6 release notes list the fix.
**What changes for a user**
- An empty or comment only `metadata.yaml` now gives a message that names the real problem.
- A `metadata.yaml` with the wrong shape still gets `Invalid file: 'metadata.yaml'`.
- A valid `metadata.yaml` is read exactly as before.
- The exit code stays 65 in both error cases.
---
- [x] I've followed the [contribution guidelines](https://github.com/canonical/charmcraft/blob/main/CONTRIBUTING.md).
- [ ] I've signed the [CLA](http://www.ubuntu.com/legal/contributors/).
- [ ] I've successfully run `make lint && make test`.
- [x] I've added or updated any relevant documentation.
- [x] In documents I changed, I [added a meta description](https://canonical-starflow.readthedocs-hosted.com/how-to/add-a-page-meta-description/) if one was missing.
- [x] I've updated the relevant release notes.
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| qwen/qwen3.6-35b-a3b |
Impact:
30
Quick Win:
22
Complexity:
10
Confidence:
85
Actionability:
80
|
needs review | Adds a check for empty metadata.yaml files to provide clearer error messages. Addresses issue #2071. PR is clean, tests updated, CI failures unrelated, awaiting maintainer review. |
Update history
| Date | Change |
|---|---|
| updated | |
| updated | |
| updated | |
| updated | |
| updated | |
| created |
Related work
-
Likely Fixed By:
canonical/charmcraft#2071
(confidence 95%)
This PR directly addresses issue #2071 which reported that empty metadata.yaml files gave confusing error messages.
Related issues
No related issues found above the similarity threshold.