{"record":{"id":"936dd36a165b5820","repo":"zeroclaw-labs/zeroclaw","slug":"slash-command-registration-failed-for-name-s","errorCode":null,"errorMessage":"slash command registration failed for '{name}' ({status}): {err}","messagePattern":"slash command registration failed for '(.+?)' \\((.+?)\\): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/discord/slash.rs","lineNumber":716,"sourceCode":"            .await\n            .map_err(reqwest::Error::without_url)?;\n        if resp.status() == reqwest::StatusCode::TOO_MANY_REQUESTS {\n            // Stop on the first 429 and surface the cooldown rather than\n            // hammering the remaining upserts into the same rate limit.\n            let until = rate_limit_deadline(resp).await;\n            ::zeroclaw_log::record!(\n                WARN,\n                ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                    .with_outcome(::zeroclaw_log::EventOutcome::Unknown)\n                    .with_attrs(::serde_json::json!({\"command\": name, \"retry_after_until\": until})),\n                \"discord slash command reconcile rate-limited; backing off\"\n            );\n            return Ok(ReconcileOutcome::RateLimited { until });\n        }\n        if !resp.status().is_success() {\n            let status = resp.status();\n            let err = resp.text().await.unwrap_or_default();\n            anyhow::bail!(\"slash command registration failed for '{name}' ({status}): {err}\");\n        }\n        upserted += 1;\n    }\n    if upserted > 0 {\n        ::zeroclaw_log::record!(\n            INFO,\n            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)\n                .with_attrs(::serde_json::json!({\"upserted\": upserted})),\n            \"discord slash commands upserted\"\n        );\n    }\n    if failed_deletes > 0 {\n        anyhow::bail!(\n            \"{failed_deletes} stale skill command delete(s) failed; \\\n             reconcile not recorded, next READY retries\"\n        );\n    }\n    Ok(ReconcileOutcome::Reconciled)","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/discord/slash.rs#L698-L734","documentation":"While reconciling, registering (creating or updating) the slash command named '{name}' failed with a non-success status; the response body is included. Registration happens per command after the listing diff decides an upsert is needed, and a 429 is converted into a RateLimited outcome before this bail.","triggerScenarios":"POST/PATCH of a command definition fails: 400 duplicate command names in the same scope, name not lowercase or over 32 chars, description over 100 chars, malformed options; 401/403 credential or app-id problems.","commonSituations":"Skill command names violating Discord's naming rules (uppercase, spaces, punctuation) after adding a new skill; two skills mapping to the same command name; description templates growing past 100 chars.","solutions":["Read '{name}' and the body: 50035-style errors point at the exact offending field","Enforce Discord's rules: name lowercase, 1–32 chars, no spaces; description ≤ 100 chars","Deduplicate command names across skills","401/403 → fix the token / application id pairing"],"exampleFix":"// before\nlet name = \"ConvertCurrency\"; // rejected: must be lowercase\n\n// after\nlet name = \"convert-currency\"; // valid: lowercase, hyphenated, <= 32 chars","handlingStrategy":"try-catch","validationCode":"// Rust — enforce Discord's command naming rules before reconcile\nfn valid_command_shape(name: &str, description: &str) -> bool {\n    let ok_name = !name.is_empty()\n        && name.len() <= 32\n        && name.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-');\n    ok_name && !description.is_empty() && description.chars().count() <= 100\n}","typeGuard":null,"tryCatchPattern":"match reconcile_slash_commands(&client, &token, &app_id, &desired, base, scope, &guilds).await {\n    Ok(outcome) => Ok(outcome),\n    Err(e) if e.to_string().contains(\"slash command registration failed\") => {\n        // payload/credential problem, not transient: the error names the command and body\n        tracing::error!(\"reconcile aborted on registration: {e}\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Lint skill command names against Discord's rules before deploying","Keep descriptions under 100 characters","Avoid two skills claiming the same command name in one scope"],"tags":["discord","slash-commands","registration","validation","naming-rules"],"backgroundTag":"discord-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}