{"record":{"id":"fb13ac29aa977a4f","repo":"iflytek/astron-agent","slug":"20201-flow-id-not-found","errorCode":"20201","errorMessage":"Flow ID not found","messagePattern":"Flow ID not found","errorType":"error_code","errorClass":"CustomException","httpStatus":null,"severity":"error","filePath":"core/workflow/api/v1/flow/layout.py","lineNumber":185,"sourceCode":"    span = Span()\n    m = Meter()\n    with span.start(\n        attributes={\"flow_id\": flow_id},\n    ) as current_span:\n        try:\n            await current_span.add_info_event_async(f\"update start: {flow_id}\")\n            del_flow_by_id(flow_id)\n            sparkflow_protocol = sanitize_protocol_document_for_use(flow.data)\n            if sparkflow_protocol:\n                if isinstance(sparkflow_protocol, str):\n                    sparkflow_protocol = json.loads(sparkflow_protocol)\n                WorkflowEngineFactory.create_engine(\n                    WorkflowDSL.model_validate(sparkflow_protocol.get(\"data\")),\n                    current_span,\n                )\n            db_flow = session.query(Flow).filter_by(id=int(flow_id)).first()\n            if not db_flow:\n                raise CustomException(CodeEnum.FLOW_NOT_FOUND_ERROR)\n\n            flow_service.update(session, db_flow, flow)\n            m.in_success_count()\n            return Resp.success(None, span.sid)\n        except ValidationError as err:\n            validation_err = _protocol_validation_exception(err)\n            current_span.record_exception(validation_err)\n            m.in_error_count(validation_err.code, span=current_span)\n            return Resp.error(\n                validation_err.code,\n                validation_err.message,\n                span.sid,\n            )\n        except CustomException as err:\n            current_span.record_exception(err)\n            m.in_error_count(err.code, span=current_span)\n            return Resp.error(err.code, err.message, span.sid)\n        except Exception as e:","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/api/v1/flow/layout.py#L167-L203","documentation":"The layout update endpoint looks up the Flow row by numeric id (session.query(Flow).filter_by(id=int(flow_id)).first()) and raises FLOW_NOT_FOUND_ERROR (20201) when no row matches. The DSL validated fine, but there is no persisted flow with that id to update.","triggerScenarios":"PUT/update on the flow layout route with a flow_id that does not exist in the flows table; int(flow_id) succeeds (numeric string) but the row was deleted or belongs to another environment/database.","commonSituations":"Client keeps a flow_id from a deleted flow; environment mismatch (dev id used against prod DB); id vs string/other-key confusion (passing app_id as flow_id); database pointed at wrong schema via config.","solutions":["Verify the flow_id exists: run SELECT id FROM flow WHERE id = <id> against the configured database.","Refresh the flow list from the API and use a current id; if the flow was deleted, recreate it.","Check DB connection config (host/database name) — the id may exist in a different environment.","Confirm you are passing the flow's numeric id, not an app_id or other identifier."],"exampleFix":"# before\nawait update_layout(flow_id=\"999999\", dsl=dsl)  # stale id\n\n# after\nflows = await list_flows()\nif any(str(f.id) == flow_id for f in flows):\n    await update_layout(flow_id=flow_id, dsl=dsl)\nelse:\n    flow_id = await create_flow(dsl=dsl)","handlingStrategy":"try-catch","validationCode":"if session.query(Flow).filter_by(id=int(flow_id)).first() is None:\n    raise ValueError(f\"flow {flow_id} does not exist\")","typeGuard":"def flow_exists(session, flow_id) -> bool:\n    return session.query(Flow).filter_by(id=int(flow_id)).first() is not None","tryCatchPattern":"try:\n    await update_layout(flow_id=flow_id, dsl=dsl)\nexcept CustomException as e:\n    if e.code == CodeEnum.FLOW_NOT_FOUND_ERROR.code:\n        flow_id = await create_flow(dsl=dsl)  # recreate or refresh id\n    else:\n        raise","preventionTips":["Refresh flow lists after deletions instead of caching ids long-term","Use the same environment/database for reads and writes","Verify you pass the flow's numeric id, not app_id or a slug"],"tags":["database","not-found","flow","crud"],"backgroundTag":"record-not-found","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}