{"record":{"id":"e191f49773fbc392","repo":"lfnovo/open-notebook","slug":"source-input-data-source-id-not-found","errorCode":null,"errorMessage":"Source '{input_data.source_id}' not found","messagePattern":"Source '(.+?)' not found","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"commands/embedding_commands.py","lineNumber":329,"sourceCode":"    Flow:\n    1. Load Source by ID\n    2. DELETE existing source_embedding records for this source\n    3. Detect content type from file path or content\n    4. Chunk text using appropriate splitter\n    5. Generate embeddings for all chunks in batches\n    6. Bulk INSERT source_embedding records\n\n    Retry Strategy:\n    - Retries up to 5 times for transient failures (network, timeout, etc.)\n    - Uses exponential-jitter backoff (1-60s)\n    - Does NOT retry permanent failures (ValueError for validation errors)\n    \"\"\"\n\n    async def embed() -> Tuple[Dict[str, Any], str]:\n        # 1. Load source\n        source = await Source.get(input_data.source_id)\n        if not source:\n            raise ValueError(f\"Source '{input_data.source_id}' not found\")\n\n        if not source.full_text or not source.full_text.strip():\n            raise ValueError(f\"Source '{input_data.source_id}' has no text to embed\")\n\n        # 2. DELETE existing embeddings (idempotency)\n        logger.debug(f\"Deleting existing embeddings for source {input_data.source_id}\")\n        await repo_query(\n            \"DELETE source_embedding WHERE source = $source_id\",\n            {\"source_id\": ensure_record_id(input_data.source_id)},\n        )\n\n        # 3. Detect content type from file path if available\n        file_path = source.asset.file_path if source.asset else None\n        content_type = detect_content_type(source.full_text, file_path)\n        logger.debug(f\"Detected content type: {content_type.value}\")\n\n        # 4. Chunk text using appropriate splitter\n        chunks = chunk_text(source.full_text, content_type=content_type)","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/commands/embedding_commands.py#L311-L347","documentation":"ValueError raised inside the source embed command when Source.get(source_id) returns nothing. It is the precondition check at the start of the embed pipeline; caught by the command wrapper and reported as success=False.","triggerScenarios":"Submitting the embed_source command (source processing worker) with a source_id that was deleted before the async job ran, or an ID from a different database.","commonSituations":"User deletes a source while its embedding job is still queued (worker backlog), or the surreal-commands worker is processing stale jobs after a DB reset.","solutions":["Check the source still exists (Sources list / SurrealDB) before resubmitting","If deleted, discard the job — nothing to embed","Keep the worker (make worker-start) running so jobs don't pile up behind deletes"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"source = await Source.get(source_id)\nif not source:\n    raise KeyError(f'source {source_id} does not exist')","typeGuard":null,"tryCatchPattern":"result = await run_command('embed_source', {'source_id': sid})\nif not result.output.get('success') and 'not found' in result.output.get('error', ''):\n    return  # source deleted while job queued","preventionTips":["Run the worker (make worker-start) so jobs process promptly and don't go stale","Check source existence before resubmitting embedding jobs","Tolerate not-found results in fire-and-forget pipelines"],"tags":["python","valueerror","embedding","source","not-found"],"backgroundTag":"record-not-found","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}