unicity-aos/aos-ce · error
Capsule.toml is not valid TOML
Error message
Capsule.toml is not valid TOML: {e} What it means
`validate_manifest` first tries to parse Capsule.toml into a TOML document; if parsing fails it stops immediately and returns a single Finding carrying the toml crate's error text. No other lints can run because there is no parse tree to inspect. This is a parse-time failure, not a semantic lint failure.
Solutions
- Read the toml error message appended to the Finding: it gives the line/column of the syntax error; fix that line.
- Validate the file with a TOML parser/linter (e.g. `taplo lint Capsule.toml`) before running the forge again.
- If generated programmatically, serialize with a TOML library instead of string concatenation.
Example fix
# before
capabilities = [uplink]
# after
capabilities = { uplink = [] }
# or use a [capabilities] table Defensive patterns
Strategy: validation
Validate before calling
// Rust: pre-validate TOML before the linter
toml::from_str::<toml::Value>(&src).map_err(|e| format!("invalid TOML: {e}"))?; Prevention
- Run a TOML linter (taplo) in CI on all Capsule.toml files.
- Generate TOML with a serializer library rather than string templates.
- Enable editor TOML syntax highlighting/format-on-save.
When it happens
Trigger: Calling `validate_manifest(toml_src)` with a string containing TOML syntax errors: unbalanced brackets, invalid key names, unterminated strings, wrong indentation in inline tables, or duplicate keys.
Common situations: Hand-editing Capsule.toml and dropping a bracket or quote, pasting YAML-style config, saving the wrong file, or an editor mangling UTF-8/special characters.
Related errors
- `capabilities` must be a TOML table.
- embedded distro has no capsules
- embedded capsule has no name
- Capability ` ` must be a list.
- Capability ` ` must be a boolean.
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/5227edb7a88b2fc9.
Report an issue: GitHub.
Appendix: source
Thrown at capsules/capsule-forge/src/checks.rs:63
let parts: Vec<&str> = v.split('.').collect();
parts.len() == 3
&& parts
.iter()
.all(|p| !p.is_empty() && p.bytes().all(|b| b.is_ascii_digit()))
}
/// A topic segment is malformed if the key has empty segments
/// (leading/trailing/consecutive dots).
fn has_empty_segments(topic: &str) -> bool {
topic.is_empty() || topic.starts_with('.') || topic.ends_with('.') || topic.contains("..")
}
/// Run all manifest lints. Returns the findings in roughly severity order.
pub(crate) fn validate_manifest(toml_src: &str) -> Vec<Finding> {
let root: Toml = match toml_src.parse() {
Ok(t) => t,
Err(e) => {
return vec![Finding::err(
format!("Capsule.toml is not valid TOML: {e}"),
"Fix the syntax error reported above; the rest of the lint can't run until it parses.",
)];
}
};
let mut out = Vec::new();
check_package(&root, &mut out);
check_component(&root, &mut out);
check_capabilities(&root, &mut out);
check_env(&root, &mut out);
let (pub_keys, sub_keys) = collect_topics(&root, &mut out);
check_tool_bus(&sub_keys, &pub_keys, &root, &mut out);
check_topic_shapes(&pub_keys, &sub_keys, &mut out);
out
}
fn check_capabilities(root: &Toml, out: &mut Vec<Finding>) {View on GitHub (pinned to f6f22024fb)