{"record":{"id":"a65a658ef0a95dc0","repo":"unicity-aos/aos-ce","slug":"subscribe-tool-v1-request-describe-is-missing-tools-won-t-be","errorCode":null,"errorMessage":"Subscribe `tool.v1.request.describe` is missing — tools won't be discoverable.","messagePattern":"Subscribe `tool\\.v1\\.request\\.describe` is missing — tools won't be discoverable\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"capsules/capsule-forge/src/checks.rs","lineNumber":286,"sourceCode":"        if !has_handler {\n            out.push(Finding::err(\n                format!(\"Subscribe `{key}` has no `handler`.\"),\n                format!(\"Add `handler = \\\"tool_execute_{tool}\\\"` to the `{key}` row.\"),\n            ));\n        }\n    }\n\n    if saw_execute_tool {\n        for required in [\"tool.v1.execute.*.result\", \"tool.v1.response.describe.*\"] {\n            if !pub_keys.iter().any(|k| k == required) {\n                out.push(Finding::err(\n                    format!(\"Mandatory publish key `{required}` is missing.\"),\n                    format!(\"Add `\\\"{required}\\\" = {{ wit = ... }}` to [publish]; tool results/describe break without it.\"),\n                ));\n            }\n        }\n        if !sub_keys.iter().any(|k| k == \"tool.v1.request.describe\") {\n            out.push(Finding::err(\n                \"Subscribe `tool.v1.request.describe` is missing — tools won't be discoverable.\",\n                \"Add `\\\"tool.v1.request.describe\\\" = { wit = ..., handler = \\\"tool_describe\\\" }` to [subscribe].\",\n            ));\n        }\n    }\n}\n\n/// Flag malformed topic keys: empty segments, or absurd depth (>8 segments).\nfn check_topic_shapes(pub_keys: &[String], sub_keys: &[String], out: &mut Vec<Finding>) {\n    for key in pub_keys.iter().chain(sub_keys) {\n        if has_empty_segments(key) {\n            out.push(Finding::err(\n                format!(\"Topic `{key}` has empty segments (leading/trailing/consecutive dots).\"),\n                \"Remove the stray dots; every segment between dots must be non-empty.\",\n            ));\n        }\n        if key.split('.').count() > 8 {\n            out.push(Finding::warn(","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/capsules/capsule-forge/src/checks.rs#L268-L304","documentation":"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.","triggerScenarios":"validate_manifest -> check_tool_bus with saw_execute_tool true and no `tool.v1.request.describe` key among sub_keys.","commonSituations":"Building a new tool capsule from a bare template, removing the describe subscription thinking it is optional, or renaming topics during a protocol migration.","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."],"exampleFix":"// before ([subscribe])\n\"tool.v1.request.execute\" = { wit = ..., handler = \"tool_execute_fetch\" }\n// after\n\"tool.v1.request.execute\" = { wit = ..., handler = \"tool_execute_fetch\" }\n\"tool.v1.request.describe\" = { wit = ..., handler = \"tool_describe\" }","handlingStrategy":"validation","validationCode":"// Ensure the describe subscription exists when the capsule executes tools\nif executes_tools {\n    assert!(subscribe.contains_key(\"tool.v1.request.describe\"), \"describe subscription missing\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["manifest","config","validation","discovery"],"backgroundTag":"missing-required-config-field","analyzedSha":"f6f22024fb1e8d122f28a1b4a9f75aee448ae839","analyzedAt":"2026-09-13T03:04:44.565Z","contentChangedAt":"2026-09-13T03:04:44.565Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}