{"record":{"id":"b06e714a23b9e417","repo":"nautechsystems/nautilus_trader","slug":"invalid-bar-step-e","errorCode":null,"errorMessage":"invalid bar step: {e}","messagePattern":"invalid bar step: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/queries.rs","lineNumber":1350,"sourceCode":"        .map_err(|e| anyhow::anyhow!(\"Failed to load quotes: {e}\"))\n    }\n\n    /// Inserts a `Bar` entry via the provided `pool`.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the SQL INSERT operation fails.\n    pub async fn add_bar(pool: &PgPool, bar: &Bar) -> anyhow::Result<()> {\n        if bar.bar_type.is_composite() {\n            anyhow::bail!(\n                \"Cannot persist bar with composite bar type {}: the bar table stores only \\\n                 the standard form; standardize the bar type before persisting\",\n                bar.bar_type,\n            );\n        }\n\n        let bar_step = i32::try_from(bar.bar_type.spec().step.get())\n            .map_err(|e| anyhow::anyhow!(\"invalid bar step: {e}\"))?;\n\n        sqlx::query(r#\"\n            INSERT INTO \"bar\" (\n                instrument_id, step, bar_aggregation, price_type, aggregation_source, open, high, low, close, volume, ts_event, ts_init, created_at, updated_at\n            ) VALUES (\n                $1, $2, $3::bar_aggregation, $4::price_type, $5::aggregation_source, $6, $7, $8, $9, $10, $11, $12, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP\n            )\n            ON CONFLICT (id)\n            DO UPDATE\n            SET\n                instrument_id = $1, step = $2, bar_aggregation = $3::bar_aggregation, price_type = $4::price_type, aggregation_source = $5::aggregation_source,\n                open = $6, high = $7, low = $8, close = $9, volume = $10, ts_event = $11, ts_init = $12, updated_at = CURRENT_TIMESTAMP\n        \"#)\n            .bind(bar.bar_type.instrument_id().to_string())\n            .bind(bar_step)\n            .bind(BarAggregationPg(bar.bar_type.spec().aggregation))\n            .bind(PriceTypePg(bar.bar_type.spec().price_type))\n            .bind(AggregationSourcePg(bar.bar_type.aggregation_source()))","sourceCodeStart":1332,"sourceCodeEnd":1368,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/queries.rs#L1332-L1368","documentation":"`add_bar` converts the bar spec's step (a u32/nonzero) into an i32 for the Postgres `step` column. If the step exceeds `i32::MAX` (or the conversion otherwise fails) this error is returned. It guards against integer overflow when binding the parameter.","triggerScenarios":"Calling `add_bar(pool, &bar)` with a bar type whose `spec().step.get()` is larger than 2147483647 — practically only from programmatically constructed bar specs with absurd step values.","commonSituations":"Constructing BarAggregation specs from unvalidated config or external input where the step is an arbitrary u64/usize; buggy aggregation code producing huge steps.","solutions":["Validate the bar spec step fits in i32 (1..=2147483647) before constructing/persisting the bar","Clamp or reject oversized steps at config load time","Check the wrapped TryFromIntError to confirm it is an out-of-range step"],"exampleFix":"// before\nsql_cache.add_bar(&pool, &bar).await?;\n// after\nassert!(bar.bar_type.spec().step.get() <= i32::MAX as u64, \"bar step too large\");\nsql_cache.add_bar(&pool, &bar).await?;","handlingStrategy":"validation","validationCode":"let step = bar.bar_type.spec().step.get();\nif step == 0 || step > i32::MAX as u64 {\n    return Err(anyhow::anyhow!(\"bar step {step} out of i32 range\"));\n}","typeGuard":"fn bar_step_fits(step: u64) -> bool { step >= 1 && step <= i32::MAX as u64 }","tryCatchPattern":"if let Err(e) = add_bar(&pool, &bar).await {\n    if e.to_string().contains(\"invalid bar step\") { /* reject or fix bar spec */ }\n    return Err(e);\n}","preventionTips":["Validate bar aggregation steps come from a bounded, sane range at config load","Never build bar specs directly from raw external integers","Test config parsing rejects absurd step values"],"tags":["validation","bars","integer-overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}