{"record":{"id":"c6fd010eadce1225","repo":"zeroclaw-labs/zeroclaw","slug":"modelpinnedproviderbuilder-pinned-model-is-requ","errorCode":null,"errorMessage":"ModelPinnedProviderBuilder: pinned_model() is required","messagePattern":"ModelPinnedProviderBuilder: pinned_model\\(\\) is required","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-providers/src/model_pin.rs","lineNumber":51,"sourceCode":"        self.pinned_model = Some(model.to_string());\n        self\n    }\n\n    /// The inner provider whose model this pin overrides. Required.\n    pub fn inner(mut self, inner: Box<dyn ModelProvider>) -> Self {\n        self.inner = Some(inner);\n        self\n    }\n\n    /// # Panics\n    /// Panics if [`Self::pinned_model`] or [`Self::inner`] was not\n    /// called — neither has a sensible default.\n    pub fn build(self) -> ModelPinnedProvider {\n        ModelPinnedProvider {\n            alias: self.alias,\n            pinned_model: self\n                .pinned_model\n                .expect(\"ModelPinnedProviderBuilder: pinned_model() is required\"),\n            inner: self\n                .inner\n                .expect(\"ModelPinnedProviderBuilder: inner() is required\"),\n        }\n    }\n}\n\nimpl ModelPinnedProvider {\n    /// Entry point. Only `alias` is taken positionally; the required\n    /// `pinned_model` and `inner` provider both go through labelled\n    /// chain methods so call sites cannot silently swap them.\n    pub fn builder(alias: &str) -> ModelPinnedProviderBuilder {\n        ModelPinnedProviderBuilder {\n            alias: alias.to_string(),\n            pinned_model: None,\n            inner: None,\n        }\n    }","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/model_pin.rs#L33-L69","documentation":"ModelPinnedProviderBuilder builds a provider that always routes to one fixed model under an alias. The pinned model has no sensible default, so build() panics if .pinned_model() was never called. The doc comment on the builder states that neither required field has a default.","triggerScenarios":"Calling ModelPinnedProvider::builder().alias(\"name\").inner(p).build() (or any construction path) without .pinned_model(\"model-id\") beforehand.","commonSituations":"Setting up model pinning for an agent alias and wiring the delegate provider but forgetting the target model; changing the pinned model to come from config and the config lookup returning nothing so the setter is skipped.","solutions":["Call .pinned_model(\"<provider-model-id>\") on the builder before .build().","If the model id comes from configuration, fail fast with a clear config error when it is missing instead of letting build() panic.","Add a test that constructs every pinned provider declared in config."],"exampleFix":"// before\nlet p = ModelPinnedProvider::builder()\n    .alias(\"fast\")\n    .inner(inner)\n    .build(); // panics: pinned_model() is required\n\n// after\nlet p = ModelPinnedProvider::builder()\n    .alias(\"fast\")\n    .pinned_model(\"gpt-4o-mini\")\n    .inner(inner)\n    .build();","handlingStrategy":"validation","validationCode":"let pinned = config.pinned_model.clone()\n    .ok_or_else(|| anyhow::anyhow!(\"agent '{}' declares model pinning without a model id\", alias))?;\nlet provider = ModelPinnedProvider::builder()\n    .alias(alias)\n    .pinned_model(pinned)\n    .inner(Box::new(inner))\n    .build();","typeGuard":null,"tryCatchPattern":"let provider = std::panic::catch_unwind(|| builder.build())\n    .map_err(|_| anyhow::anyhow!(\"ModelPinnedProviderBuilder contract violated: pinned_model/inner required\"))?;","preventionTips":["Provide pinned_model and inner together; they are both mandatory with no defaults.","Validate model-pinning config entries at load time so a missing model id is a config error, not a runtime panic.","Unit-test construction of every pinned provider declared in config."],"tags":["rust","builder","panic","model-pinning","provider"],"backgroundTag":"builder-missing-required-field","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}