lfnovo/open-notebook · error · InvalidInputError
ID cannot be empty
Error message
ID cannot be empty
What it means
ObjectModel.get(id) rejects empty/falsy IDs up front with InvalidInputError before touching the database. An empty string, None, or otherwise falsy id can never name a record, so the method fails fast.
Source
Thrown at open_notebook/domain/base.py:107
result = await repo_query(query)
objects = []
for obj in result:
try:
objects.append(target_class(**obj))
except Exception as e:
logger.critical(f"Error creating object: {str(e)}")
return objects
except Exception as e:
logger.error(f"Error fetching all {cls.table_name}: {str(e)}")
logger.exception(e)
raise DatabaseOperationError(e)
@classmethod
async def get(cls: Type[T], id: str) -> T:
if not id:
raise InvalidInputError("ID cannot be empty")
try:
# Get the table name from the ID (everything before the first colon)
table_name = id.split(":")[0] if ":" in id else id
# 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:View on GitHub (pinned to a7de90d38a)
Solutions
- Validate/require the id at the API boundary (Path(..., min_length=1) in FastAPI)
- Default to a 404 or 400 response when the id is missing instead of calling get()
- Check truthiness before calling: if not id: raise HTTPException(404)
Example fix
# before
obj = await Note.get(note_id) # note_id may be ''
# after
if not note_id:
raise HTTPException(status_code=404, detail="Note id required")
obj = await Note.get(note_id) Defensive patterns
Strategy: validation
Validate before calling
if not id or not isinstance(id, str):
raise HTTPException(status_code=404, detail="Missing id")
obj = await Note.get(id) Type guard
def is_valid_record_id(id: object) -> bool:
return isinstance(id, str) and bool(id.strip()) and ":" in id Prevention
- Require non-empty path params at the FastAPI layer (min_length=1)
- Never default id parameters to '' or None when a fetch follows
- Return early with 400/404 when id is missing instead of calling the ORM
When it happens
Trigger: await MyModel.get(''), await MyModel.get(None), or a value pulled from an unvalidated request path/query param like /notes/ that arrives as empty string.
Common situations: API route handlers passing through unvalidated path parameters; frontend sending undefined which serializes to ''; default arguments like id='' used as placeholders.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Cannot delete object without an ID
- Failed to check environment status
- No embedding model configured. Please configure one in the M
- Item type must be either 'source' or 'note'
- Invalid model type. Must be one of: {valid_types}
AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27).
Data as JSON: /api/errors/6307a43312ecd16b.
Report an issue: GitHub.