{"record":{"id":"25625d99c3e03eb4","repo":"vectordotdev/vector","slug":"argument-must-be-a-string-25625d","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/find_vector_metrics.rs","lineNumber":16,"sourceCode":"use std::{collections::BTreeMap, sync::LazyLock};\nuse vector_vrl_category::Category;\nuse vrl::prelude::expression::Expr;\n\nuse vrl::prelude::*;\n\nuse crate::common::{\n    metric_into_vrl, metrics_vrl_typedef, resolve_tags, validate_tags, Error, MetricsStorage,\n};\n\nfn find_metrics(\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    Ok(Value::Array(\n        metrics_storage\n            .find_metrics(&key_str, tags)\n            .iter()\n            .map(metric_into_vrl)\n            .collect(),\n    ))\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.\",","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-vrl/metrics/src/find_vector_metrics.rs#L1-L34","documentation":"find_vector_metrics' helper unwraps its key with key.as_str().expect(\"argument must be a string\") (lib/vector-vrl/metrics/src/find_vector_metrics.rs). The key parameter is declared required BYTES in the function's parameter list, and the VRL compiler type-checks call sites, so this panic indicates the runtime value violated a compile-time guarantee (internal invariant) rather than a user scripting mistake.","triggerScenarios":"The compiled function executing with a non-bytes key Value — normally impossible because find_vector_metrics(42) is rejected during VRL compilation; triggered by compiler regressions, mixed vector-vrl crate versions, or code invoking the helper directly (unit tests, embeddings).","commonSituations":"VRL compiler development and fuzzing; custom builds with partially upgraded vector-vrl-* crates; direct helper calls in internal tests.","solutions":["Align vector-vrl crates to a single Vector release","Use string literals or to_string! for the key in VRL programs","Invoke functions only through compiled programs in embedding code","Report compiler-invariant breaks with a minimal VRL program upstream"],"exampleFix":"# before (vrl)\nfind_vector_metrics(key)   # key: any\n\n# after (vrl)\nfind_vector_metrics(to_string!(key))","handlingStrategy":"type-guard","validationCode":"# Statically-typed key argument\nfind_vector_metrics(to_string!(key))","typeGuard":"fn is_bytes(v: &vrl::value::Value) -> bool {\n    matches!(v, vrl::value::Value::Bytes(_))\n}","tryCatchPattern":null,"preventionTips":["Use string literals for metric name filters","vector vrl check the program during development","Align vector-vrl-metrics and compiler crate versions"],"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-14T00:17:10.932Z"}