{"record":{"id":"629d4a26e92ef76d","repo":"zeroclaw-labs/zeroclaw","slug":"microsoft365-client-secret-must-not-be-empty-when-629d4a","errorCode":null,"errorMessage":"microsoft365.client_secret must not be empty when auth_flow is client_credentials","messagePattern":"microsoft365\\.client_secret must not be empty when auth_flow is client_credentials","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":21762,"sourceCode":"                .map(str::trim)\n                .filter(|s| !s.is_empty());\n            if client.is_none() {\n                anyhow::bail!(\n                    \"microsoft365.client_id must not be empty when microsoft365 is enabled\"\n                );\n            }\n            let flow = self.microsoft365.auth_flow.trim();\n            if flow != \"client_credentials\" && flow != \"device_code\" {\n                anyhow::bail!(\"microsoft365.auth_flow must be client_credentials or device_code\");\n            }\n            if flow == \"client_credentials\"\n                && self\n                    .microsoft365\n                    .client_secret\n                    .as_deref()\n                    .is_none_or(|s| s.trim().is_empty())\n            {\n                anyhow::bail!(\n                    \"microsoft365.client_secret must not be empty when auth_flow is client_credentials\"\n                );\n            }\n        }\n\n        validate_plugin_entries(&self.plugins)?;\n\n        // MCP\n        if self.mcp.enabled {\n            validate_mcp_config(&self.mcp)?;\n        }\n\n        // Knowledge graph\n        if self.knowledge.enabled {\n            if self.knowledge.max_nodes == 0 {\n                validation_bail!(\n                    InvalidNumericRange,\n                    \"knowledge.max_nodes\",","sourceCodeStart":21744,"sourceCodeEnd":21780,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L21744-L21780","documentation":"Second copy of the client_secret guard (schema.rs:21755-21765): when trimmed auth_flow is client_credentials, client_secret must be present and non-whitespace. Identical to error 473 except the message omits quotes around the flow name; the first validation block shadows it in current builds. Same fix applies regardless of which variant fires.","triggerScenarios":"auth_flow = \"client_credentials\" with client_secret missing/blank on an enabled [microsoft365] section, in a build where the second block is the effective one.","commonSituations":"Version-skewed log analysis; review of the duplicated block.","solutions":["Set a non-empty microsoft365.client_secret, or switch to device_code flow","Key automated handling on 'microsoft365.client_secret', not the message string","Remove the duplicated block when maintaining this file"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Same guard as error 473:\nfn m365_secret_ok(m: &zeroclaw_config::Microsoft365Config) -> bool {\n    m.auth_flow.trim() != \"client_credentials\"\n        || m.client_secret.as_deref().map(str::trim).is_some_and(|s| !s.is_empty())\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = config.validate() {\n    if err.to_string().contains(\"microsoft365.client_secret\") {\n        // inject the secret or switch flows — covers both wording variants\n    }\n}","preventionTips":["Match on 'microsoft365.client_secret' rather than the exact sentence","Eliminate the duplicated validation block in schema.rs:21727-21766"],"tags":["configuration","validation","microsoft365","secrets","duplicate-code","zeroclaw","rust"],"backgroundTag":"required-config-field-missing","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}