{"record":{"id":"6359a277f1351157","repo":"unicity-aos/aos-ce","slug":"subscribe-key-has-priority-outside-the-u32-range","errorCode":null,"errorMessage":"Subscribe `{key}` has priority outside the u32 range.","messagePattern":"Subscribe `(.+?)` has priority outside the u32 range\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"capsules/capsule-forge/src/checks.rs","lineNumber":241,"sourceCode":"    let sub_table = root.get(\"subscribe\").and_then(Toml::as_table);\n    let mut saw_execute_tool = false;\n\n    for key in sub_keys {\n        if let Some(entry) = sub_table.and_then(|table| table.get(key)) {\n            let has_handler = entry\n                .get(\"handler\")\n                .and_then(Toml::as_str)\n                .is_some_and(|handler| !handler.is_empty());\n            if entry.get(\"priority\").is_some() && !has_handler {\n                out.push(Finding::err(\n                    format!(\"Subscribe `{key}` sets `priority` without a `handler`.\"),\n                    \"Add a real handler binding or remove priority from the ACL-only subscription.\",\n                ));\n            }\n            if let Some(priority) = entry.get(\"priority\") {\n                if let Some(priority) = priority.as_integer() {\n                    if !(0..=u32::MAX.into()).contains(&priority) {\n                        out.push(Finding::err(\n                            format!(\"Subscribe `{key}` has priority outside the u32 range.\"),\n                            \"Use an integer from 0 through 4294967295; lower values run first.\",\n                        ));\n                    }\n                } else {\n                    out.push(Finding::err(\n                        format!(\"Subscribe `{key}` priority must be an integer.\"),\n                        \"Use an integer from 0 through 4294967295; lower values run first.\",\n                    ));\n                }\n            }\n        }\n\n        let Some(tool) = key.strip_prefix(\"tool.v1.execute.\") else {\n            continue;\n        };\n        // The `*.result` publish key would also strip; skip non-tool shapes.\n        if tool.contains('*') || tool.contains('.') {","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/capsules/capsule-forge/src/checks.rs#L223-L259","documentation":"During manifest validation, capsule-forge checks each [subscribe] entry's `priority` field against the u32 range (0..=4294967295) because the tool bus dispatches messages by priority-ordered queueing backed by u32. A value outside that range (e.g. negative or > u32::MAX) cannot be represented and would corrupt ordering, so the check fails the manifest.","triggerScenarios":"Running `capsule-forge validate` (validate_manifest -> check_tool_bus) when a `[subscribe]` entry sets `priority = <integer>` that is negative or greater than 4294967295.","commonSituations":"Copy-pasting priority values from documentation of other systems using i64 priorities, computing priority via arithmetic that overflows, or hand-editing the manifest and typing an extra digit.","solutions":["Clamp or change the priority value in the [subscribe] entry to an integer in 0..4294967295.","Remember lower values run first; re-scale your priority scheme to fit the u32 range.","Re-run the manifest validation to confirm the finding clears."],"exampleFix":"// before ([subscribe])\n\"tool.v1.request.describe\" = { wit = ..., handler = \"tool_describe\", priority = 5000000000 }\n// after\n\"tool.v1.request.describe\" = { wit = ..., handler = \"tool_describe\", priority = 100 }","handlingStrategy":"validation","validationCode":"// Rust: check before writing the manifest\nfn valid_priority(p: i64) -> bool { (0..=u32::MAX as i64).contains(&p) }\nassert!(valid_priority(100));","typeGuard":"fn as_u32_priority(v: &serde_json::Value) -> Option<u32> {\n    v.as_i64().filter(|p| (0..=u32::MAX as i64).contains(p)).map(|p| p as u32)\n}","tryCatchPattern":null,"preventionTips":["Define priorities as u32 constants instead of literals in templates.","Add a CI lint that rejects priority values outside 0..=4294967295.","Document the u32 limit and 'lower runs first' rule next to the manifest schema."],"tags":["manifest","config","validation","toml"],"backgroundTag":"value-out-of-range","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"}