BoundaryML/baml · error
feedback field "{key}" must be a string
Error message
feedback field "{key}" must be a string What it means
In `baml feedback`, if a --json payload supplies "title" or "description" with a non-string JSON value (number, bool, object, null), the command errors rather than silently dropping it — the local record and PostHog preview previously dropped such values via as_str.
Source
Thrown at baml_language/crates/baml_cli/src/feedback_command.rs:403
.map(String::as_str)
.filter(|k| !matches!(*k, "title" | "description"))
.collect();
if !unknown.is_empty() {
return Err(anyhow::anyhow!(
"unknown feedback field(s) {}; only \"title\" and \
\"description\" are sent (attach files with --files)",
unknown.join(", ")
));
}
// Validate types, not just names: a non-string field would ship to
// PostHog while the preview and the local record (which read via
// `as_str`) silently dropped it.
for key in ["title", "description"] {
if let Some(value) = obj.get(key)
&& !value.is_string()
{
return Err(anyhow::anyhow!("feedback field \"{key}\" must be a string"));
}
}
let title = obj.get("title").and_then(Value::as_str).unwrap_or("");
if title.trim().is_empty() {
return Err(anyhow::anyhow!(
"feedback needs a title; pass --title \"...\" or a JSON payload \
with a \"title\" field"
));
}
Ok(from_json)
}
/// Shows exactly what a report contains and how it is attributed.
fn print_preview(&self, payload: &Value, identified: bool, email: Option<&str>) {
if identified {
println!(
"reporting to Boundary as {}:",View on GitHub (pinned to bd85ce9dee)
Solutions
- Quote the value so it is a JSON string: --json '{"title":"123"}'.
- Use null by omitting the field entirely rather than passing non-string values.
- Validate the payload with jq before passing it (jq -e '.title | type == "string"').
Example fix
// before
baml feedback --json '{"title":123}'
// after
baml feedback --json '{"title":"123"}' Defensive patterns
Strategy: type-guard
Validate before calling
// ensure fields are strings before invoking
const p = JSON.parse(payload);
if (p.title !== undefined && typeof p.title !== 'string') throw new Error('title must be a string');
if (p.description !== undefined && typeof p.description !== 'string') throw new Error('description must be a string'); Type guard
const isStr = (v) => typeof v === 'string'; const validFeedback = (p) => ['title','description'].every(k => p[k] === undefined || isStr(p[k]));
Try / catch
try {
run(`baml feedback --json '${payload}'`);
} catch (e) {
if (String(e).includes('must be a string')) {
const p = JSON.parse(payload);
['title','description'].forEach(k => { if (p[k] !== undefined) p[k] = String(p[k]); });
run(`baml feedback --json '${JSON.stringify(p)}'`);
}
} Prevention
- Coerce dynamic values to strings before building the JSON payload
- Omit optional fields instead of passing null
- Validate payload types with jq or a schema before invoking
When it happens
Trigger: `baml feedback --json '{"title":123}'` or `--json '{"description":{"text":"x"}}'` — obj.get(key) exists but !value.is_string() for title or description.
Common situations: Building JSON payloads programmatically where numbers/booleans slip in; quoting mistakes in shell producing unquoted values; copying payloads that use null for empty fields.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- unknown feedback field(s) {}; only "title" and "description"
- feedback payload must be a JSON object like {"title": "..."}
- type `{ty}` can't be passed through auto-CLI; deliver it via
- feedback needs a title; pass --title "..." or a JSON payload
- invalid Go SDK import path `{import_path}`
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/12553ebddcbf96e9.
Report an issue: GitHub.