netdata/netdata · error · anyhow::Error

{name}() expects a string argument

Error message

{name}() expects a string argument

What it means

`one_string_arg` verified the argument count (exactly 1 via `one_arg`) but the parsed value expression is not string-typed — `is_string_expression()` returned false. The DSL is typed enough to reject passing a number, field, or list where a string action (SetName, ClassifyRole, ...) requires one.

Source

Thrown at src/crates/netflow-plugin/src/enrichment/classifiers/parse/value.rs:25

    }
    parse_value_expr(args[0].trim())
}

fn three_args(name: &str, args: &[String]) -> Result<(ValueExpr, ValueExpr, ValueExpr)> {
    if args.len() != 3 {
        anyhow::bail!("{name}() expects exactly 3 arguments");
    }
    Ok((
        parse_value_expr(args[0].trim())?,
        parse_value_expr(args[1].trim())?,
        parse_value_expr(args[2].trim())?,
    ))
}

pub(super) fn one_string_arg(name: &str, args: &[String]) -> Result<ValueExpr> {
    let value = one_arg(name, args)?;
    if !value.is_string_expression() {
        anyhow::bail!("{name}() expects a string argument");
    }
    Ok(value)
}

pub(super) fn three_string_args(
    name: &str,
    args: &[String],
) -> Result<(ValueExpr, ValueExpr, ValueExpr)> {
    let (arg1, arg2, arg3) = three_args(name, args)?;
    if !arg1.is_string_expression() || !arg2.is_string_expression() || !arg3.is_string_expression()
    {
        anyhow::bail!("{name}() expects string arguments");
    }
    validate_literal_regex_value(&arg2, name)?;
    Ok((arg1, arg2, arg3))
}

pub(super) fn validate_literal_regex_value(value: &ValueExpr, context: &str) -> Result<()> {

View on GitHub (pinned to 4864de85e2)

Solutions

  1. Pass a string-typed expression: a quoted literal, a string flow field, or a Format() call.
  2. Convert numbers explicitly with `Format("{}", DstPort)` if you need them in a string action.

Example fix

// before
SetName(DstPort)

// after
SetName(Format("port-{}", DstPort))
Defensive patterns

Strategy: type-guard

Type guard

// Author-side check: the argument must be a quoted literal, string field, or Format()
fn is_stringy(term: &str) -> bool {
    let t = term.trim();
    t.starts_with('"') || t.starts_with("Format(") || is_known_string_field(t)
}
fn is_known_string_field(f: &str) -> bool {
    matches!(f, "SrcIP" | "DstIP" | "InIfDescription" | "OutIfDescription" | "ExporterName")
}

Prevention

When it happens

Trigger: `SetName(42)`, `ClassifySite(DstPort)`, or any 1-arg string action whose argument parses to a NumberLiteral, numeric Field, or List value expression.

Common situations: Passing a numeric literal or numeric flow field to a naming/classification action; assuming implicit number-to-string coercion (the DSL does not coerce).

Related errors


AI-assisted analysis of netdata/netdata@4864de85e2 (2026-08-15). Data as JSON: /api/errors/c70dbfbbf45bc6c2. Report an issue: GitHub.