{"record":{"id":"175fecab1566b865","repo":"neondatabase/neon","slug":"unknown-scheduling-policy-s-try-active-pause","errorCode":null,"errorMessage":"Unknown scheduling policy '{s}', try active,pause,decomissioned","messagePattern":"Unknown scheduling policy '(.+?)', try active,pause,decomissioned","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/pageserver_api/src/controller_api.rs","lineNumber":454,"sourceCode":"#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Debug)]\npub enum SkSchedulingPolicy {\n    Active,\n    Activating,\n    Pause,\n    Decomissioned,\n}\n\nimpl FromStr for SkSchedulingPolicy {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"active\" => Self::Active,\n            \"activating\" => Self::Activating,\n            \"pause\" => Self::Pause,\n            \"decomissioned\" => Self::Decomissioned,\n            _ => {\n                return Err(anyhow::anyhow!(\n                    \"Unknown scheduling policy '{s}', try active,pause,decomissioned\"\n                ));\n            }\n        })\n    }\n}\n\nimpl From<SkSchedulingPolicy> for String {\n    fn from(value: SkSchedulingPolicy) -> String {\n        use SkSchedulingPolicy::*;\n        match value {\n            Active => \"active\",\n            Activating => \"activating\",\n            Pause => \"pause\",\n            Decomissioned => \"decomissioned\",\n        }\n        .to_string()\n    }","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/libs/pageserver_api/src/controller_api.rs#L436-L472","documentation":"SkSchedulingPolicy::from_str rejects any string that is not one of the storage controller's tenant scheduling policies. The accepted literals are 'active', 'activating', 'pause', and 'decomissioned' -- note the single-'m' spelling of 'decomissioned' is the one the code matches. The error hint text lists only three of the four; 'activating' is also valid input.","triggerScenarios":"PUT/GET on the storage controller scheduling-policy API or the neon CLI equivalent with an unsupported value: 'decommissioned' (correct English spelling), 'paused', 'disabled', 'drain', 'ACTIVE', or trailing whitespace/quotes around the value. Example: 'curl -X PUT .../control/v1/tenant/{tenant_id}/scheduling?policy=paused'.","commonSituations":"Typing the correct English 'decommissioned' instead of the code's 'decomissioned'; reusing pageserver or safekeeper vocabulary on the storage controller; clients written against an older controller release whose policy set differed; untrimmed values from configuration files.","solutions":["Use exactly one of: active, activating, pause, decomissioned (single m)","For decommissioning, mirror the literal in the error hint: 'decomissioned'","Compare against the SkSchedulingPolicy FromStr impl in your checkout/release; the policy set changes between versions","Trim whitespace and avoid quoting the value; URL-encode it when sent via query string"],"exampleFix":"# before\ncurl -X PUT 'http://localhost:1234/control/v1/tenant/68d.../scheduling?policy=decommissioned'\n# -> Unknown scheduling policy 'decommissioned', try active,pause,decomissioned\n\n# after (note the single-m spelling)\ncurl -X PUT 'http://localhost:1234/control/v1/tenant/68d.../scheduling?policy=decomissioned'","handlingStrategy":"type-guard","validationCode":"const SK_SCHEDULING_POLICIES: &[&str] = &[\"active\", \"activating\", \"pause\", \"decomissioned\"];\n\nfn validate_policy(policy: &str) -> Result<(), String> {\n    if SK_SCHEDULING_POLICIES.contains(&policy) {\n        Ok(())\n    } else {\n        Err(format!(\n            \"invalid scheduling policy {policy:?}; expected one of {SK_SCHEDULING_POLICIES:?} \\\n             (note: 'decomissioned' is spelled with a single m)\"\n        ))\n    }\n}","typeGuard":"fn is_valid_sk_scheduling_policy(s: &str) -> bool {\n    matches!(s, \"active\" | \"activating\" | \"pause\" | \"decomissioned\")\n}","tryCatchPattern":"match SkSchedulingPolicy::from_str(policy) {\n    Ok(p) => p,\n    Err(e) => {\n        // FromStr has no typed error; match on the message and re-raise with the valid set\n        if e.to_string().starts_with(\"Unknown scheduling policy\") {\n            return Err(anyhow::anyhow!(\"{e}; valid: active, activating, pause, decomissioned\"));\n        }\n        return Err(e);\n    }\n}","preventionTips":["Expose the accepted policy strings as a const array next to your CLI/API and build choices from it","Add shell completion / enum flags to CLIs so users pick policies interactively instead of typing them","Pin a test that round-trips every enum variant through FromStr/Display after any policy-set change","Beware the 'decomissioned' single-m spelling when porting scripts from docs"],"tags":["rust","storage-controller","enum","configuration","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}