fix(core): validate run exists before creating step/step_metrics (#9382)
Checks if the referenced run_id exists in the runs table before inserting steps and step_metrics. If the run doesn't exist (deleted or failed creation), sets run_id to None instead of hitting ForeignKeyViolationError on fk_steps_run_id. Fixes https://us5.datadoghq.com/error-tracking/issue/a1768774-d691-11f0-9330-da7ad0900000 🐾 Generated with [Letta Code](https://letta.com) Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -7,8 +7,12 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from letta.helpers.singleton import singleton
|
from letta.helpers.singleton import singleton
|
||||||
|
from letta.log import get_logger
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
from letta.orm.errors import NoResultFound
|
from letta.orm.errors import NoResultFound
|
||||||
from letta.orm.message import Message as MessageModel
|
from letta.orm.message import Message as MessageModel
|
||||||
|
from letta.orm.run import Run as RunModel
|
||||||
from letta.orm.sqlalchemy_base import AccessType
|
from letta.orm.sqlalchemy_base import AccessType
|
||||||
from letta.orm.step import Step as StepModel
|
from letta.orm.step import Step as StepModel
|
||||||
from letta.orm.step_metrics import StepMetrics as StepMetricsModel
|
from letta.orm.step_metrics import StepMetrics as StepMetricsModel
|
||||||
@@ -231,11 +235,15 @@ class StepManager:
|
|||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if run_id:
|
||||||
|
run_exists = await session.get(RunModel, run_id)
|
||||||
|
if not run_exists:
|
||||||
|
logger.warning("Step run_id %s references non-existent run, setting to None", run_id)
|
||||||
|
step_data["run_id"] = None
|
||||||
|
|
||||||
new_step = StepModel(**step_data)
|
new_step = StepModel(**step_data)
|
||||||
await new_step.create_async(session, no_commit=True, no_refresh=True)
|
await new_step.create_async(session, no_commit=True, no_refresh=True)
|
||||||
pydantic_step = new_step.to_pydantic()
|
pydantic_step = new_step.to_pydantic()
|
||||||
# context manager now handles commits
|
|
||||||
# await session.commit()
|
|
||||||
return pydantic_step
|
return pydantic_step
|
||||||
|
|
||||||
@enforce_types
|
@enforce_types
|
||||||
@@ -593,6 +601,12 @@ class StepManager:
|
|||||||
"base_template_id": base_template_id,
|
"base_template_id": base_template_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if run_id:
|
||||||
|
run_exists = await session.get(RunModel, run_id)
|
||||||
|
if not run_exists:
|
||||||
|
logger.warning("StepMetrics run_id %s references non-existent run, setting to None", run_id)
|
||||||
|
metrics_data["run_id"] = None
|
||||||
|
|
||||||
metrics = StepMetricsModel(**metrics_data)
|
metrics = StepMetricsModel(**metrics_data)
|
||||||
await metrics.create_async(session)
|
await metrics.create_async(session)
|
||||||
return metrics.to_pydantic()
|
return metrics.to_pydantic()
|
||||||
|
|||||||
Reference in New Issue
Block a user