{"record":{"id":"eb215389908602fa","repo":"databendlabs/databend","slug":"s3-params-must-remain-s3","errorCode":null,"errorMessage":"S3 params must remain S3","messagePattern":"S3 params must remain S3","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/meta/app-storage/src/storage_params.rs","lineNumber":1143,"sourceCode":"        let params = StorageParams::S3(StorageS3Config {\n            endpoint_url: \"http://provider.example:9000\".to_string(),\n            region: \"provider-region\".to_string(),\n            bucket: \"provider-bucket\".to_string(),\n            root: \"provider/root\".to_string(),\n            enable_virtual_host_style: true,\n            access_key_id: \"provider-key\".to_string(),\n            secret_access_key: \"provider-secret\".to_string(),\n            security_token: \"provider-token\".to_string(),\n            master_key: \"provider-master-key\".to_string(),\n            role_arn: \"provider-role\".to_string(),\n            external_id: \"provider-external-id\".to_string(),\n            disable_credential_loader: true,\n            allow_credential_chain: Some(true),\n            ..Default::default()\n        });\n\n        let StorageParams::S3(location) = params.without_credentials() else {\n            unreachable!(\"S3 params must remain S3\");\n        };\n        assert_eq!(\"http://provider.example:9000\", location.endpoint_url);\n        assert_eq!(\"provider-region\", location.region);\n        assert_eq!(\"provider-bucket\", location.bucket);\n        assert_eq!(\"provider/root\", location.root);\n        assert!(location.enable_virtual_host_style);\n        assert!(location.access_key_id.is_empty());\n        assert!(location.secret_access_key.is_empty());\n        assert!(location.security_token.is_empty());\n        assert!(location.master_key.is_empty());\n        assert!(location.role_arn.is_empty());\n        assert!(location.external_id.is_empty());\n        assert!(!location.disable_credential_loader);\n        assert_eq!(None, location.allow_credential_chain);\n    }\n}\n","sourceCodeStart":1125,"sourceCodeEnd":1160,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/meta/app-storage/src/storage_params.rs#L1125-L1160","documentation":"This unreachable!() lives in a test in storage_params.rs that calls without_credentials() on a StorageParams::S3 and asserts the result is still StorageParams::S3. If the credential-stripping function ever changed the variant type (e.g. converting S3 params to another storage flavor or dropping them), the pattern match fails and the test panics with 'S3 params must remain S3'. It guards the contract that removing credentials never alters the storage variant.","triggerScenarios":"Modifying StorageParams::without_credentials or the S3 storage-param types so it no longer returns a StorageParams::S3 variant, then running the storage-params tests.","commonSituations":"Refactors of StorageParams (adding new storage backends, changing without_credentials to a generic transform); accidental use of a constructor that wraps S3 in another enum variant.","solutions":["Ensure without_credentials() rebuilds StorageParams::S3 with the same location fields minus credentials","Keep the S3-specific fields (endpoint_url, region, bucket, root, enable_virtual_host_style) intact when stripping secrets","Run the storage_params tests (`cargo test -p meta-app-storage -- storage_params`) after changes"],"exampleFix":"// before\npub fn without_credentials(&self) -> StorageParams { /* returns wrong variant */ }\n// after\npub fn without_credentials(&self) -> StorageParams {\n    match self {\n        StorageParams::S3(loc) => StorageParams::S3(loc.without_credentials()),\n        other => other.clone(),\n    }\n}","handlingStrategy":"validation","validationCode":"assert!(matches!(params, StorageParams::S3(_)), \"without_credentials requires S3 params\");","typeGuard":null,"tryCatchPattern":"let StorageParams::S3(loc) = params.without_credentials() else {\n    log::error!(\"without_credentials changed variant\");\n    return Err(ErrorCode::InternalError(\"S3 params must remain S3\"));\n};","preventionTips":["Implement without_credentials per-variant, always rebuilding the same variant","Add tests for every StorageParams variant when adding backends","Never replace the S3 variant during credential stripping"],"tags":["rust","tests","storage","s3"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}