lfnovo/open-notebook · error · NotFoundError
Object with id {id} not found - {str(e)}
Error message
Object with id {id} not found - {str(e)} What it means
The broad except in get() converts any unexpected exception during fetch/deserialization into NotFoundError with the original message appended. Unfortunately this masks genuine infrastructure errors (connection loss, schema mismatch) as 'not found', because the except wraps the whole body including the success path's constructor call.
Source
Thrown at open_notebook/domain/base.py:130
# If we're calling from a specific subclass and IDs match, use that class
if cls.table_name and cls.table_name == table_name:
target_class: Type[T] = cls
else:
# Otherwise, find the appropriate subclass based on table_name
found_class = cls._get_class_by_table_name(table_name)
if not found_class:
raise InvalidInputError(f"No class found for table {table_name}")
target_class = cast(Type[T], found_class)
result = await repo_query("SELECT * FROM $id", {"id": ensure_record_id(id)})
if result:
return target_class(**result[0])
else:
raise NotFoundError(f"{table_name} with id {id} not found")
except Exception as e:
logger.error(f"Error fetching object with id {id}: {str(e)}")
logger.exception(e)
raise NotFoundError(f"Object with id {id} not found - {str(e)}")
@classmethod
def _get_class_by_table_name(cls, table_name: str) -> Optional[Type["ObjectModel"]]:
"""Find the appropriate subclass based on table_name."""
def get_all_subclasses(c: Type["ObjectModel"]) -> List[Type["ObjectModel"]]:
all_subclasses: List[Type["ObjectModel"]] = []
for subclass in c.__subclasses__():
all_subclasses.append(subclass)
all_subclasses.extend(get_all_subclasses(subclass))
return all_subclasses
for subclass in get_all_subclasses(ObjectModel):
if hasattr(subclass, "table_name") and subclass.table_name == table_name:
return subclass
return None
async def save(self) -> None:View on GitHub (pinned to a7de90d38a)
Solutions
- Read the full message suffix and the logged traceback to find the real cause
- If it's connection-related, restore SurrealDB and retry (make database / check API logs)
- If it's deserialization, fix schema drift between the Pydantic model and stored records
- Treat ambiguous 'not found' during outages as errors, not 404s — check system health before returning 404 to users
Example fix
# before
except NotFoundError:
return JSONResponse(status_code=404) # may mask a DB outage
# after
except NotFoundError as e:
if "connection" in str(e).lower():
return JSONResponse(status_code=503, content={"detail": "database unavailable"})
return JSONResponse(status_code=404, content={"detail": "not found"}) Defensive patterns
Strategy: fallback
Validate before calling
null
Try / catch
from open_notebook.domain.errors import NotFoundError
try:
obj = await Note.get(nid)
except NotFoundError as e:
msg = str(e).lower()
if any(k in msg for k in ("connection", "timeout", "serialization")):
raise HTTPException(status_code=503, detail="Storage error")
raise HTTPException(status_code=404, detail="Not found") Prevention
- Always read the '- {cause}' suffix and logged traceback before assuming 404
- Alert when NotFoundError rates spike during incidents — often masking outages
- Check DB health before reporting not-found to users during degraded periods
When it happens
Trigger: DB connection drops mid-query, ensure_record_id raises on a malformed id, or target_class(**result[0]) fails on schema drift — all surface as NotFoundError('Object with id ... not found - <cause>').
Common situations: Developer sees 'not found' but the record clearly exists; usually a SurrealDB outage or model/record field mismatch hiding in the - {str(e)} suffix. Read the log (logger.exception prints the traceback) to identify the real cause.
Related errors
- {table_name} with id {id} not found
- Error fetching all {cls.table_name}: {str(e)}
- No class found for table {table_name}
- Error saving record: {e}
- Failed to delete {self.__class__.table_name}
AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27).
Data as JSON: /api/errors/69746c283d3a1754.
Report an issue: GitHub.