{"record":{"id":"e6564639cec6fc85","repo":"HKUDS/Vibe-Trading","slug":"cannot-mark-a-model-approved-from-validation-statu","errorCode":null,"errorMessage":"cannot mark a model APPROVED from validation_status={current.value!r}; it must reach VALIDATED first","messagePattern":"cannot mark a model APPROVED from validation_status=(.+?); it must reach VALIDATED first","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/strategy_store/models.py","lineNumber":233,"sourceCode":"\n    The only hard rule: a model cannot be marked ``APPROVED`` unless it is\n    already ``VALIDATED`` (re-approving an already-``APPROVED`` model is a\n    harmless no-op transition). Every other transition is left to caller\n    discretion.\n\n    Args:\n        current: The model's validation status before the change.\n        new: The requested validation status.\n\n    Raises:\n        ValueError: if *new* is ``APPROVED`` while *current* is anything\n            other than ``VALIDATED`` or ``APPROVED``.\n    \"\"\"\n    if new is ValidationStatus.APPROVED and current not in (\n        ValidationStatus.VALIDATED,\n        ValidationStatus.APPROVED,\n    ):\n        raise ValueError(\n            \"cannot mark a model APPROVED from validation_status=\"\n            f\"{current.value!r}; it must reach VALIDATED first\"\n        )\n\n\ndef validate_model_registration(artifact: Artifact) -> None:\n    \"\"\"Validate that *artifact* carries the minimum model-registration fields.\n\n    A model registration without a stated intended use or a stated\n    limitation is, for governance purposes, not actually registered — so\n    both fields are required and must be non-blank.\n\n    Args:\n        artifact: The artifact/model record to validate.\n\n    Raises:\n        ValueError: if ``intended_use`` or ``limitations`` is missing or\n            consists only of whitespace.","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/strategy_store/models.py#L215-L251","documentation":"validate_validation_status_transition enforces the state machine: a model artifact can only become APPROVED from VALIDATED (or stay APPROVED). Trying to jump from UNVALIDATED, IN_VALIDATION, or REJECTED straight to APPROVED raises ValueError. Called by register_artifact and update_artifact.","triggerScenarios":"register_artifact(Artifact(..., validation_status=ValidationStatus.APPROVED)) on a brand-new record; update_artifact moving status from 'unvalidated' or 'rejected' to 'approved' in one step.","commonSituations":"Re-registering a previously approved model from a config dump without replaying its validation history; scripts that stamp APPROVED at import time; tests asserting the guard.","solutions":["First set status to VALIDATED (record the validation run/date), then a separate update to APPROVED","If the model was already validated elsewhere, re-import it with VALIDATED status and then approve","Never seed new artifacts with APPROVED in registration payloads"],"exampleFix":"# before\nstore.register_artifact(Artifact(name='m1', universe='u1', validation_status=ValidationStatus.APPROVED, ...))\n# after\nstore.register_artifact(Artifact(name='m1', universe='u1', validation_status=ValidationStatus.VALIDATED, validation_date='2024-05-01', ...))\nstore.update_artifact('m1', Artifact(..., validation_status=ValidationStatus.APPROVED, ...))","handlingStrategy":"validation","validationCode":"from agent.src.strategy_store.models import ValidationStatus\nORDER = ['unvalidated','in_validation','validated','approved']\ndef can_approve(current: ValidationStatus) -> bool:\n    return current in (ValidationStatus.VALIDATED, ValidationStatus.APPROVED)","typeGuard":"def transition_allowed(current: ValidationStatus, new: ValidationStatus) -> bool:\n    return not (new is ValidationStatus.APPROVED and current not in (ValidationStatus.VALIDATED, ValidationStatus.APPROVED))","tryCatchPattern":"try:\n    store.update_artifact(name, updated)\nexcept ValueError as e:\n    if 'APPROVED' in str(e): first persist VALIDATED with a validation_date, then retry the approve\n    else: raise","preventionTips":["Model the state machine explicitly in registration scripts","Two-step promote: VALIDATED then APPROVED","Never default new artifacts to APPROVED in config dumps"],"tags":["python","state-machine","model-registry","validation"],"backgroundTag":"invalid-state-transition","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}