{"record":{"id":"6a69c65f13e8012e","repo":"vectordotdev/vector","slug":"argument-must-be-a-string-6a69c6","errorCode":null,"errorMessage":"argument must be a string","messagePattern":"argument must be a string","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vector-vrl/metrics/src/get_vector_metric.rs","lineNumber":15,"sourceCode":"use std::{collections::BTreeMap, sync::LazyLock};\n\nuse vector_vrl_category::Category;\nuse vrl::prelude::{expression::Expr, *};\n\nuse crate::common::{\n    metric_into_vrl, metrics_vrl_typedef, resolve_tags, validate_tags, Error, MetricsStorage,\n};\n\nfn get_metric(\n    metrics_storage: &MetricsStorage,\n    key: Value,\n    tags: BTreeMap<String, String>,\n) -> Result<Value, ExpressionError> {\n    let key_str = key.as_str().expect(\"argument must be a string\");\n    let value = match metrics_storage.get_metric(&key_str, tags) {\n        Some(value) => metric_into_vrl(&value),\n        None => Value::Null,\n    };\n    Ok(value)\n}\n\nstatic DEFAULT_TAGS: LazyLock<Value> = LazyLock::new(|| Value::Object(BTreeMap::new()));\n\nstatic PARAMETERS: LazyLock<Vec<Parameter>> = LazyLock::new(|| {\n    vec![\n        Parameter::required(\"key\", kind::BYTES, \"The metric name to search.\"),\n        Parameter::optional(\n            \"tags\",\n            kind::OBJECT,\n            \"Tags to filter the results on. Values in this object support wildcards ('*') to match on parts of the tag value.\",\n        )\n        .default(&DEFAULT_TAGS),","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-vrl/metrics/src/get_vector_metric.rs#L1-L33","documentation":"get_vector_metric's helper starts with key.as_str().expect(\"argument must be a string\") (lib/vector-vrl/metrics/src/get_vector_metric.rs). Its key parameter is defined as Parameter::required(\"key\", kind::BYTES, ...), so VRL's compiler enforces bytes at the call site; the expect is a runtime assertion of that compile-time contract and signals an internal invariant violation if it ever fires.","triggerScenarios":"Executing get_vector_metric with a runtime key Value that is not bytes/string — prevented by compilation in normal flows (get_vector_metric(true) fails to compile); occurs only with VRL compiler bugs, version-mismatched vector-vrl crates, or direct helper use outside the compile pipeline.","commonSituations":"Embedding VRL without the type-checking pass; dependency skew between vector-vrl-metrics and the compiler; compiler regression testing.","solutions":["Upgrade Vector/vector-vrl crates in lockstep","Pass statically-typed strings: get_vector_metric(\"buffer_byte_size\", tags = {...})","Use the compiled Program API for embedding","Report reproducible stock-build panics to vectordot/vector"],"exampleFix":"# before (vrl)\nget_vector_metric(key)   # key: any\n\n# after (vrl)\nget_vector_metric(to_string!(key))","handlingStrategy":"type-guard","validationCode":"# Literal or coerced metric key\nget_vector_metric(to_string!(key))","typeGuard":"fn is_bytes(v: &vrl::value::Value) -> bool {\n    matches!(v, vrl::value::Value::Bytes(_))\n}","tryCatchPattern":null,"preventionTips":["Quote metric keys as string literals","Compile-check remap transforms referencing metrics functions","Keep VRL crates on one release"],"tags":["vector","vrl","metrics","type-invariant","panic","internal"],"backgroundTag":"type-invariant-violation","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}