{"record":{"id":"a6bd590ed38e89ea","repo":"epi052/feroxbuster","slug":"extractor-requires-a-url-or-a-feroxresponse-be-specified-as","errorCode":null,"errorMessage":"Extractor requires a URL or a FeroxResponse be specified as well as a Handles object","messagePattern":"Extractor requires a URL or a FeroxResponse be specified as well as a Handles object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/extractor/builder.rs","lineNumber":132,"sourceCode":"\n    /// builder call to set `target`\n    pub fn target(&mut self, target: ExtractionTarget) -> &mut Self {\n        self.target = target;\n        self\n    }\n\n    /// builder call to set `response`\n    pub fn response(&mut self, response: &'a FeroxResponse) -> &mut Self {\n        self.response = Some(response);\n        self\n    }\n\n    /// finalize configuration of `ExtractorBuilder` and return an `Extractor`\n    ///\n    /// requires either `with_url` or `with_response` to have been used in the build process\n    pub fn build(&self) -> Result<Extractor<'a>> {\n        if (self.url.is_empty() && self.response.is_none()) || self.handles.is_none() {\n            bail!(\"Extractor requires a URL or a FeroxResponse be specified as well as a Handles object\")\n        }\n\n        Ok(Extractor {\n            links_regex: Regex::new(LINKFINDER_REGEX).unwrap(),\n            robots_regex: Regex::new(ROBOTS_TXT_REGEX).unwrap(),\n            url_regex: Regex::new(URL_CHARS_REGEX).unwrap(),\n            response: self.response,\n            url: self.url.to_owned(),\n            handles: self.handles.as_ref().unwrap().clone(),\n            target: self.target,\n        })\n    }\n}\n","sourceCodeStart":114,"sourceCodeEnd":146,"githubUrl":"https://github.com/epi052/feroxbuster/blob/1f595dab5c76858d5a14fbc47dabf2563d729c62/src/extractor/builder.rs#L114-L146","documentation":"ExtractorBuilder::build requires either a URL (with_url) or a FeroxResponse (with_response) plus a Handles object; otherwise no extractor can be constructed since there is nothing to scrape links from and no configuration context.","triggerScenarios":"Calling build() without having chained with_url()/with_response(), or without with_handles() — e.g. a builder created with ExtractorBuilder::default() and immediately built.","commonSituations":"Refactors dropping a builder method call; copy-pasted builder code missing with_url when switching from response-based to URL-based extraction; forgetting with_handles after changing constructor signatures across versions.","solutions":["Chain .with_url(&url) (or .with_response(&response)) before build()","Chain .with_handles(handles.clone()) before build()","Verify the builder call chain compiles to include both a source (url/response) and handles"],"exampleFix":"// before\nlet extractor = ExtractorBuilder::default().build()?;\n// after\nlet extractor = ExtractorBuilder::default()\n    .with_url(\"https://example.com\")\n    .with_handles(handles.clone())\n    .build()?;","handlingStrategy":"validation","validationCode":"fn builder_ready(url: &str, response: Option<&FeroxResponse>, handles: Option<Handles>) -> bool {\n    (!url.is_empty() || response.is_some()) && handles.is_some()\n}\nif !builder_ready(&url, response.as_ref(), handles) {\n    return Err(\"extractor needs url or response, plus handles\".into());\n}","typeGuard":"fn has_handles(h: &Option<Handles>) -> bool { h.is_some() }","tryCatchPattern":"let extractor = builder.build().map_err(|e| {\n    eprintln!(\"builder incomplete: {e}; did you forget with_url/with_response or with_handles?\");\n    e\n})?;","preventionTips":["Chain with_url or with_response and with_handles in the same builder expression","Prefer builder methods over ExtractorBuilder::default() to avoid incomplete states","Add a unit test that builds an extractor the way production code does"],"tags":["builder","missing-argument","extractor"],"backgroundTag":"missing-required-argument","analyzedSha":"1f595dab5c76858d5a14fbc47dabf2563d729c62","analyzedAt":"2026-09-13T19:33:06.208Z","contentChangedAt":"2026-09-13T19:33:06.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}