{"record":{"id":"1d974bc4f34d2f1f","repo":"unicity-aos/aos-ce","slug":"topic-key-has-more-than-8-segments-likely-a-mistake","errorCode":null,"errorMessage":"Topic `{key}` has more than 8 segments — likely a mistake.","messagePattern":"Topic `(.+?)` has more than 8 segments — likely a mistake\\.","errorType":"validation","errorClass":"Finding","httpStatus":null,"severity":"warning","filePath":"capsules/capsule-forge/src/checks.rs","lineNumber":304,"sourceCode":"            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(\n                format!(\"Topic `{key}` has more than 8 segments — likely a mistake.\"),\n                \"Flatten the topic; deep topic trees usually indicate a naming error.\",\n            ));\n        }\n    }\n    if out.iter().all(|f| f.level != \"error\") {\n        out.push(Finding::info(\n            \"No blocking manifest errors found.\",\n            \"Build with `aos capsule build`, then install with `aos capsule install`.\",\n        ));\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::validate_manifest;\n\n    #[test]","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/capsules/capsule-forge/src/checks.rs#L286-L322","documentation":"check_topic_shapes validates every declared topic key in the manifest. Topics with more than 8 dot-separated segments trigger this warning because deeply nested topic trees usually indicate a naming mistake (e.g. embedding parameters into topic segments). The manifest still validates unless errors are also present, but the topic shape is flagged as suspicious.","triggerScenarios":"validate_manifest -> check_topic_shapes processes a topic key where key.split('.').count() > 8, e.g. `tool.v1.execute.a.b.c.d.e.f.result`.","commonSituations":"Encoding per-request IDs or user data into topic names instead of payload fields; over-hierarchical naming conventions; concatenating topic prefixes repeatedly when building topics programmatically.","solutions":["Flatten the topic to 8 or fewer segments; move variable data (IDs, params) into the message payload, not the topic name.","Review the naming scheme against the documented topic taxonomy in forge_guide.","If topics are built in code, check for accidental repeated prefix concatenation."],"exampleFix":"// before: stuffing a request id into the topic\nlet topic = format!(\"tool.v1.execute.echo.request.{req_id}.payload.result\");\n// after: keep the topic stable, send the id in the payload\nlet topic = \"tool.v1.execute.echo.result\";\nlet payload = serde_json::json!({ \"request_id\": req_id });","handlingStrategy":"validation","validationCode":"# fail CI on over-deep topics\nfor t in $(tomlq -r '(.publish // {}) + (.subscribe // {}) | keys[]' capsule.toml); do\n  segs=$(echo \"$t\" | awk -F. '{print NF}'); [ \"$segs\" -gt 8 ] && echo \"topic too deep: $t\" && exit 1\ndone","typeGuard":"fn topic_depth_ok(topic: &str) -> bool { topic.split('.').count() <= 8 }","tryCatchPattern":null,"preventionTips":["Put variable data in the payload, never in topic segments","Keep topic names under the documented 8-segment limit","Review programmatic topic construction for prefix duplication"],"tags":["manifest","topics","naming","validation"],"backgroundTag":"invalid-identifier-format","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"}