FuelLabs/fuel-core · error · anyhow::Error
Missing column. Check the schema!
Error message
Missing column. Check the schema!
What it means
Encoder::write in the parquet encoder asks the row-group writer for its next column and treats None as a schema violation ('Missing column. Check the schema!', crates/chain-config/src/config/state/parquet/encode.rs:70). The encoder is created with a single byte-array column, so this error means the parquet writer yielded no column where one was guaranteed — an internal invariant break, typically writer misuse (writing after close, reusing a writer whose state advanced after a swallowed error) or a parquet-crate version mismatch.
Source
Thrown at crates/chain-config/src/config/state/parquet/encode.rs:70
.build()
.expect("This is a valid schema");
Type::group_type_builder("unimportant")
.with_fields(vec![Arc::new(data)])
.build()
.expect("This is a valid schema")
}
}
impl<W> Encoder<W>
where
W: Write + Send,
{
pub fn write(&mut self, elements: Vec<Vec<u8>>) -> anyhow::Result<()> {
let mut group = self.writer.next_row_group()?;
let mut column = group
.next_column()?
.ok_or_else(|| anyhow::anyhow!("Missing column. Check the schema!"))?;
let values = elements.into_iter().map(Into::into).collect_vec();
column
.typed::<ByteArrayType>()
.write_batch(&values, None, None)?;
column.close()?;
group.close()?;
Ok(())
}
pub fn close(self) -> anyhow::Result<()> {
self.writer.close()?;
Ok(())
}
}
View on GitHub (pinned to b9d4d170da)
Solutions
- Create a fresh Encoder per snapshot table via its constructor so the schema always contains the expected ByteArrayType column.
- Propagate writer errors and never reuse an encoder after a failed write.
- Pin the parquet crate to the version fuel-core chain-config was built and tested with.
- If it reproduces with a freshly constructed encoder, file an upstream bug — the encoder's own schema contract was violated.
Defensive patterns
Strategy: validation
Try / catch
match encoder.write(elements) {
Err(e) if e.to_string().contains("Missing column") => {
// internal invariant break: discard the writer, build a fresh Encoder, and fail loudly if it repeats
return Err(e.context("parquet encoder invariant violated; recreate encoder"));
}
other => other?,
} Prevention
- Create a fresh Encoder per table via its constructor so the single-column schema is guaranteed.
- Propagate every writer error; never continue writing after a failure.
- Keep the parquet dependency version aligned with what chain-config was built against.
When it happens
Trigger: Calling Encoder::write(elements) after the writer's row group/column state has been consumed or closed, or with a schema that ends up with zero leaf columns.
Common situations: Upgrading the parquet dependency changes next_column semantics; continuing to write after a prior error was ignored; constructing the writer outside Encoder::new so the expected single-column schema is absent.
Related errors
- No block height found
- No config found
- Fragments don't have the same encoding and cannot be merged.
- Missing code for contract: {id}
- Missing utxo for contract: {id}
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/5b0a5033eda7f726.
Report an issue: GitHub.