{"record":{"id":"6be7474e19f76ab7","repo":"spacedriveapp/spacedrive","slug":"entry-has-no-content-id","errorCode":null,"errorMessage":"Entry has no content_id","messagePattern":"Entry has no content_id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/media/ocr/processor.rs","lineNumber":75,"sourceCode":"\t\t}\n\n\t\tif entry.content_id.is_none() {\n\t\t\treturn false;\n\t\t}\n\n\t\tentry.mime_type.as_ref().map_or(false, |m| {\n\t\t\tsuper::is_ocr_supported(m, self.library.core_context().file_type_registry())\n\t\t})\n\t}\n\n\tpub async fn process(\n\t\t&self,\n\t\tdb: &sea_orm::DatabaseConnection,\n\t\tentry: &ProcessorEntry,\n\t) -> Result<ProcessorResult> {\n\t\tlet content_id = entry\n\t\t\t.content_id\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Entry has no content_id\"))?;\n\n\t\tdebug!(\"→ Extracting text via OCR for: {}\", entry.path.display());\n\n\t\t// Extract text\n\t\tlet extracted_text = super::extract_text_from_file(&entry.path, &self.languages).await?;\n\n\t\tif extracted_text.is_empty() {\n\t\t\tdebug!(\"No text extracted from: {}\", entry.path.display());\n\t\t\treturn Ok(ProcessorResult::success(0, 0));\n\t\t}\n\n\t\tdebug!(\"✓ Extracted {} characters of text\", extracted_text.len());\n\n\t\t// Update content_identity with extracted text\n\t\tuse crate::infra::db::entities::content_identity;\n\n\t\tlet ci = content_identity::Entity::find_by_id(content_id)\n\t\t\t.one(db)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/media/ocr/processor.rs#L57-L93","documentation":"The OCR processor requires entry.content_id because extracted text is written into the content_identity row. process() unwraps the Option and errors when None: the entry passed the mime-type check but was never identified (no content identity created), so there is nowhere to store OCR output.","triggerScenarios":"Running the OCR processor on entries the identifier has not processed yet (pipeline ordering wrong); entries whose identification failed or was skipped; manually enqueuing entries into the processor without the identify step.","commonSituations":"Processor registry ordering changed so OCR runs before identification; a new file picked up mid-write before identify completed; identification errors silently skipped an entry.","solutions":["Ensure the identifier processor runs before OCR in the pipeline ordering","Add a content_id requirement to the processor's wants_to_process check so unqualified entries are filtered, not errored","Re-run identification on affected entries, then re-queue OCR"],"exampleFix":"// before (wants_to_process)\nentry.mime_type.as_ref().map_or(false, |m| {\n    super::is_ocr_supported(m, self.library.core_context().file_type_registry())\n})\n\n// after: also require a content identity, mirroring process()'s hard requirement\nentry.mime_type.as_ref().map_or(false, |m| {\n    super::is_ocr_supported(m, self.library.core_context().file_type_registry())\n}) && entry.content_id.is_some()","handlingStrategy":"type-guard","validationCode":"// Only enqueue OCR when a content identity exists\nif entry.content_id.is_some() {\n    ocr_processor.enqueue(entry).await?;\n}","typeGuard":"fn is_ocr_eligible(entry: &ProcessorEntry, registry: &FileTypeRegistry) -> bool {\n    entry.content_id.is_some()\n        && entry\n            .mime_type\n            .as_ref()\n            .map_or(false, |m| super::is_ocr_supported(m, registry))\n}","tryCatchPattern":"match ocr.process(db, &entry).await {\n    Ok(res) => { /* aggregate results */ }\n    Err(e) if e.to_string().contains(\"Entry has no content_id\") => {\n        tracing::debug!(path = %entry.path.display(), \"skipping OCR: entry not yet identified\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep identification ahead of OCR in processor pipeline ordering","Mirror every hard requirement of process() in wants_to_process filters","Re-queue skipped entries after identification completes"],"tags":["ocr","media-processors","pipeline-ordering","content-identity"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}