{"record":{"id":"292d118789a0f451","repo":"GraphiteEditor/Graphite","slug":"resource-storage-not-initialized","errorCode":null,"errorMessage":"Resource storage not initialized","messagePattern":"Resource storage not initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/resource_storage/resource_storage_message_handler.rs","lineNumber":42,"sourceCode":"\n\tfn garbage_collect(&self, used: &[ResourceHash]) {\n\t\tself.inner.garbage_collect(used)\n\t}\n}\n\n#[derive(ExtractField)]\npub struct ResourceStorageMessageHandler {\n\tstorage: Option<Arc<dyn ResourceStorage>>,\n}\n\nimpl ResourceStorageMessageHandler {\n\tpub fn new(resource_storage: Arc<dyn ResourceStorage>) -> Self {\n\t\tSelf { storage: Some(resource_storage) }\n\t}\n\n\tpub fn resources(&self) -> Box<dyn LoadResource> {\n\t\tBox::new(ResourcesHandle {\n\t\t\tinner: self.storage.clone().expect(\"Resource storage not initialized\"),\n\t\t})\n\t}\n\n\tpub fn resources_mut(&self) -> ResourcesHandle {\n\t\tResourcesHandle {\n\t\t\tinner: self.storage.clone().expect(\"Resource storage not initialized\"),\n\t\t}\n\t}\n}\n\nimpl std::fmt::Debug for ResourceStorageMessageHandler {\n\tfn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n\t\tf.debug_struct(\"ResourceStorageMessageHandler\").finish_non_exhaustive()\n\t}\n}\n\nimpl Default for ResourceStorageMessageHandler {\n\t#[cfg(not(test))]","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/resource_storage/resource_storage_message_handler.rs#L24-L60","documentation":"ResourceStorageMessageHandler wraps an Option<Arc<dyn ResourceStorage>>; resources() clones it with .expect(\"Resource storage not initialized\"). The non-test Default impl deliberately constructs Self { storage: None } (tests get a HashMapResourceStorage instead), so this panic fires exactly when resources() is called on a default-constructed handler - i.e., the editor was wired up without ever providing a resource storage backend. The sibling process_message handles the None case gracefully, so only these accessor call sites panic.","triggerScenarios":"Constructing the handler via Default::default() (as some generic message-handler scaffolding does) and then calling resources(), which dereferences the never-initialized storage.","commonSituations":"New entry points (CLI, tests, embedded scenarios) building the editor state with Default instead of ResourceStorageMessageHandler::new(storage); refactors that reset the portfolio/message handlers to defaults at runtime.","solutions":["Always construct via ResourceStorageMessageHandler::new(storage) at startup so storage is Some from the beginning","Change resources()/resources_mut() to return Option (or a Result) and let callers skip resource-dependent features when storage is absent","Log loudly at startup when resource storage is not provided so mis-wiring is visible before any panic"],"exampleFix":"// before\npub fn resources(&self) -> Box<dyn LoadResource> {\n\tBox::new(ResourcesHandle { inner: self.storage.clone().expect(\"Resource storage not initialized\") })\n}\n\n// after\npub fn resources(&self) -> Option<Box<dyn LoadResource>> {\n\tself.storage.clone().map(|inner| Box::new(ResourcesHandle { inner }) as Box<dyn LoadResource>)\n}","handlingStrategy":"validation","validationCode":"if let Some(storage) = &self.storage {\n\tlet handle = ResourcesHandle { inner: storage.clone() };\n\t// use handle\n} else {\n\tlog::error!(\"resource storage not initialized; skipping resource feature\");\n}","typeGuard":"fn is_initialized(handler: &ResourceStorageMessageHandler) -> bool {\n\thandler.storage.is_some()\n}","tryCatchPattern":null,"preventionTips":["Construct the handler with ::new(storage) in every entry point instead of Default","Make accessors return Option and let callers degrade gracefully","Log at startup when resource storage is missing so mis-wiring is caught early"],"tags":["rust","dependency-injection","initialization","resource-storage","panic"],"backgroundTag":"service-not-initialized","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}