{"record":{"id":"01e9c2846087454d","repo":"risingwavelabs/risingwave","slug":"invalid-partition-fields-hint-supported-forma","errorCode":null,"errorMessage":"Invalid partition fields: {}\nHINT: Supported formats are column, transform(column), transform(n,column), transform(n, column)","messagePattern":"Invalid partition fields: (.+?)\nHINT: Supported formats are column, transform\\(column\\), transform\\(n,column\\), transform\\(n, column\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/create_table.rs","lineNumber":446,"sourceCode":"                 columns [{}].\",\n                idx,\n                rw_field.name,\n                arrow_field.name(),\n                arrow_schema.fields().iter().map(|f| f.name()).join(\", \"),\n            );\n        }\n    }\n\n    Ok(())\n}\n\npub fn parse_partition_by_exprs(\n    expr: String,\n) -> std::result::Result<Vec<(String, Transform)>, anyhow::Error> {\n    // captures column, transform(column), transform(n,column), transform(n, column)\n    let re = Regex::new(r\"(?<transform>\\w+)(\\(((?<n>\\d+)?(?:,|(,\\s)))?(?<field>\\w+)\\))?\").unwrap();\n    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();","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/create_table.rs#L428-L464","documentation":"`parse_partition_by_exprs` parses the sink's partition spec expression with a regex capturing `column`, `transform(column)`, `transform(n,column)`. If the whole expression does not match the pattern, it bails with `Invalid partition fields` plus a hint of supported formats.","triggerScenarios":"Called from `create_table_if_not_exists_impl` / `build_iceberg_engine_sink_options` when the `partition_by` sink option contains syntax the regex can't parse — e.g., commas separating multiple top-level parts in a way the regex rejects, quoted identifiers, spaces inside column names, or transform names with special characters.","commonSituations":"Users write `partition_by = 'bucket[8](id), truncate(3,name)'` style (bracket syntax instead of `bucket(8, id)`); quotes around identifiers; multi-expression strings with separators not supported; typos like extra parentheses or empty parts.","solutions":["Rewrite the partition spec using the supported syntax: `col`, `transform(col)`, `transform(n,col)`, or `transform(n, col)` (e.g., `bucket(8, id)`, `truncate(3, name)`).","Remove quotes and unsupported separators between parts.","Validate each part matches `\\w+` identifier rules (letters, digits, underscores only)."],"exampleFix":"// before\npartition_by = 'bucket[8](id)'\n// after\npartition_by = 'bucket(8, id)'","handlingStrategy":"validation","validationCode":"// validate partition_by syntax before passing it to the sink\nconst RE: &str = r\"^(\\w+(\\(\\d+\\s*,\\s*\\w+\\)|\\(\\w+\\))?)(\\s*,\\s*\\w+(\\(\\d+\\s*,\\s*\\w+\\)|\\(\\w+\\))?)*$\";\nif !Regex::new(RE).unwrap().is_match(&partition_by) {\n    return Err(format!(\"invalid partition_by: {partition_by}\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only documented forms: col, transform(col), transform(n,col), transform(n, col).","Avoid bracket syntax (bucket[8]) and quoted identifiers in partition_by.","Keep identifiers to \\w+ characters (letters, digits, underscores)."],"tags":["iceberg","partitioning","syntax","config"],"backgroundTag":"invalid-argument-format","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"}