unicity-aos/aos-ce · error
Subscribe `tool.v1.request.describe` is missing — tools…
Error message
Subscribe `tool.v1.request.describe` is missing — tools won't be discoverable.
What it means
A capsule that executes tools must subscribe to `tool.v1.request.describe` so it can answer discovery/describe queries; without it the tool is invisible to discovery tooling. check_tool_bus emits this error when [subscribe] lacks that exact key, alongside guidance to bind it to the `tool_describe` handler.
Solutions
- Add `"tool.v1.request.describe" = { wit = ..., handler = "tool_describe" }` to [subscribe].
- Ensure the `tool_describe` export exists in the capsule and implements the describe contract.
- Re-run validation to confirm both describe publish and subscribe wiring.
Example fix
// before ([subscribe])
"tool.v1.request.execute" = { wit = ..., handler = "tool_execute_fetch" }
// after
"tool.v1.request.execute" = { wit = ..., handler = "tool_execute_fetch" }
"tool.v1.request.describe" = { wit = ..., handler = "tool_describe" } Defensive patterns
Strategy: validation
Validate before calling
// Ensure the describe subscription exists when the capsule executes tools
if executes_tools {
assert!(subscribe.contains_key("tool.v1.request.describe"), "describe subscription missing");
} Prevention
- Treat `tool.v1.request.describe` as boilerplate in every tool capsule template.
- Wire the `tool_describe` handler together with the subscription in scaffolding.
- Run validation in CI so discoverability regressions fail the build.
When it happens
Trigger: validate_manifest -> check_tool_bus with saw_execute_tool true and no `tool.v1.request.describe` key among sub_keys.
Common situations: Building a new tool capsule from a bare template, removing the describe subscription thinking it is optional, or renaming topics during a protocol migration.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Subscribe ` ` has priority outside the u32 range.
- Subscribe ` ` priority must be an integer.
- Subscribe ` ` has no `handler`.
- Mandatory publish key
- Topic ` ` has empty segments (leading/trailing/consecutive…
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/a65a658ef0a95dc0.
Report an issue: GitHub.
Appendix: source
Thrown at capsules/capsule-forge/src/checks.rs:286
if !has_handler {
out.push(Finding::err(
format!("Subscribe `{key}` has no `handler`."),
format!("Add `handler = \"tool_execute_{tool}\"` to the `{key}` row."),
));
}
}
if saw_execute_tool {
for required in ["tool.v1.execute.*.result", "tool.v1.response.describe.*"] {
if !pub_keys.iter().any(|k| k == required) {
out.push(Finding::err(
format!("Mandatory publish key `{required}` is missing."),
format!("Add `\"{required}\" = {{ wit = ... }}` to [publish]; tool results/describe break without it."),
));
}
}
if !sub_keys.iter().any(|k| k == "tool.v1.request.describe") {
out.push(Finding::err(
"Subscribe `tool.v1.request.describe` is missing — tools won't be discoverable.",
"Add `\"tool.v1.request.describe\" = { wit = ..., handler = \"tool_describe\" }` to [subscribe].",
));
}
}
}
/// Flag malformed topic keys: empty segments, or absurd depth (>8 segments).
fn check_topic_shapes(pub_keys: &[String], sub_keys: &[String], out: &mut Vec<Finding>) {
for key in pub_keys.iter().chain(sub_keys) {
if has_empty_segments(key) {
out.push(Finding::err(
format!("Topic `{key}` has empty segments (leading/trailing/consecutive dots)."),
"Remove the stray dots; every segment between dots must be non-empty.",
));
}
if key.split('.').count() > 8 {
out.push(Finding::warn(View on GitHub (pinned to f6f22024fb)