{"record":{"id":"1bb85c17a87c77f9","repo":"risingwavelabs/risingwave","slug":"the-n-must-be-set-with-bucket-and-truncate","errorCode":null,"errorMessage":"The `n` must be set with `bucket` and `truncate`","messagePattern":"The `n` must be set with `bucket` and `truncate`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/create_table.rs","lineNumber":463,"sourceCode":"    if !re.is_match(&expr) {\n        bail!(format!(\n            \"Invalid partition fields: {}\\nHINT: Supported formats are column, transform(column), transform(n,column), transform(n, column)\",\n            expr\n        ))\n    }\n    let caps = re.captures_iter(&expr);\n\n    let mut partition_columns = vec![];\n\n    for mat in caps {\n        let (column, transform) = if mat.name(\"n\").is_none() && mat.name(\"field\").is_none() {\n            (&mat[\"transform\"], Transform::Identity)\n        } else {\n            let mut func = mat[\"transform\"].to_owned();\n            if func == \"bucket\" || func == \"truncate\" {\n                let n = &mat\n                    .name(\"n\")\n                    .ok_or_else(|| anyhow!(\"The `n` must be set with `bucket` and `truncate`\"))?\n                    .as_str();\n                func = format!(\"{func}[{n}]\");\n            }\n            (\n                &mat[\"field\"],\n                Transform::from_str(&func)\n                    .with_context(|| format!(\"invalid transform function {}\", func))?,\n            )\n        };\n        partition_columns.push((column.to_owned(), transform));\n    }\n    Ok(partition_columns)\n}\n\npub fn parse_order_key_exprs(\n    expr: String,\n) -> std::result::Result<Vec<IcebergOrderKeyField>, anyhow::Error> {\n    let mut order_keys = Vec::new();","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/create_table.rs#L445-L481","documentation":"When parsing a `bucket(...)` or `truncate(...)` partition transform, the `n` (parameter count/width) capture group is mandatory. If the regex matched a `bucket`/`truncate` transform but the optional `n` group is absent, the code errors with `The n must be set with bucket and truncate`.","triggerScenarios":"Called from `parse_partition_by_exprs`: an expression like `bucket(id)` or `truncate(name)` where the transform requires a numeric parameter (bucket count / truncate width) but none was provided between the parentheses.","commonSituations":"Users copy Spark's `truncate(col)`-style syntax without the width, or write `bucket(col)` forgetting the bucket count; mixing up Iceberg's parameterized transforms with parameterless ones (year/month/day/hour).","solutions":["Add the numeric parameter: use `bucket(N, col)` and `truncate(W, col)` with N/W as integers.","Use parameterless transforms (`year(col)`, `month(col)`, `day(col)`, `hour(col)`) if no n is intended.","Re-run sink creation with the corrected `partition_by` option."],"exampleFix":"// before\npartition_by = 'bucket(id)'\n// after\npartition_by = 'bucket(16, id)'","handlingStrategy":"validation","validationCode":"// ensure bucket/truncate always carry their numeric parameter\nfn validate_partition_expr(e: &str) -> Result<(), String> {\n    for part in e.split(',') {\n        let p = part.trim();\n        if (p.starts_with(\"bucket(\") || p.starts_with(\"truncate(\"))\n            && !p.contains(',') {\n            return Err(format!(\"{p} needs an n parameter: e.g. bucket(16, col)\"));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write bucket(N, col) and truncate(W, col) with explicit integers.","Use year/month/day/hour for parameterless time transforms.","Lint sink DDL for parameterless bucket/truncate before deployment."],"tags":["iceberg","partitioning","missing-argument","config"],"backgroundTag":"missing-required-argument","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}