@@ -54,30 +54,20 @@ pub(crate) async fn init_if_enabled(
5454 return None ;
5555 }
5656 } ;
57- let should_backfill = match runtime. get_backfill_state ( ) . await {
58- Ok ( state) => state. status != codex_state :: BackfillStatus :: Complete ,
57+ let backfill_state = match runtime. get_backfill_state ( ) . await {
58+ Ok ( state) => state,
5959 Err ( err) => {
6060 warn ! (
6161 "failed to read backfill state at {}: {err}" ,
6262 config. codex_home. display( )
6363 ) ;
64- true
64+ return None ;
6565 }
6666 } ;
67- if should_backfill {
68- let runtime_for_backfill = Arc :: clone ( & runtime) ;
69- let config_for_backfill = config. clone ( ) ;
70- let otel_for_backfill = otel. cloned ( ) ;
71- tokio:: task:: spawn ( async move {
72- metadata:: backfill_sessions (
73- runtime_for_backfill. as_ref ( ) ,
74- & config_for_backfill,
75- otel_for_backfill. as_ref ( ) ,
76- )
77- . await ;
78- } ) ;
67+ if backfill_state. status != codex_state:: BackfillStatus :: Complete {
68+ metadata:: backfill_sessions ( runtime. as_ref ( ) , config, otel) . await ;
7969 }
80- Some ( runtime)
70+ require_backfill_complete ( runtime, config . codex_home . as_path ( ) ) . await
8171}
8272
8373/// Get the DB if the feature is enabled and the DB exists.
@@ -88,13 +78,14 @@ pub async fn get_state_db(config: &Config, otel: Option<&OtelManager>) -> Option
8878 {
8979 return None ;
9080 }
91- codex_state:: StateRuntime :: init (
81+ let runtime = codex_state:: StateRuntime :: init (
9282 config. codex_home . clone ( ) ,
9383 config. model_provider_id . clone ( ) ,
9484 otel. cloned ( ) ,
9585 )
9686 . await
97- . ok ( )
87+ . ok ( ) ?;
88+ require_backfill_complete ( runtime, config. codex_home . as_path ( ) ) . await
9889}
9990
10091/// Open the state runtime when the SQLite file exists, without feature gating.
@@ -112,7 +103,31 @@ pub async fn open_if_present(codex_home: &Path, default_provider: &str) -> Optio
112103 )
113104 . await
114105 . ok ( ) ?;
115- Some ( runtime)
106+ require_backfill_complete ( runtime, codex_home) . await
107+ }
108+
109+ async fn require_backfill_complete (
110+ runtime : StateDbHandle ,
111+ codex_home : & Path ,
112+ ) -> Option < StateDbHandle > {
113+ match runtime. get_backfill_state ( ) . await {
114+ Ok ( state) if state. status == codex_state:: BackfillStatus :: Complete => Some ( runtime) ,
115+ Ok ( state) => {
116+ warn ! (
117+ "state db backfill not complete at {} (status: {})" ,
118+ codex_home. display( ) ,
119+ state. status. as_str( )
120+ ) ;
121+ None
122+ }
123+ Err ( err) => {
124+ warn ! (
125+ "failed to read backfill state at {}: {err}" ,
126+ codex_home. display( )
127+ ) ;
128+ None
129+ }
130+ }
116131}
117132
118133fn cursor_to_anchor ( cursor : Option < & Cursor > ) -> Option < codex_state:: Anchor > {
0 commit comments