block/buzz · error · IngestError::Rejected
invalid archived value: {v} (must be "true" or "false")
Error message
invalid archived value: {v} (must be "true" or "false") What it means
Thrown when a kind:9002 event carries an "archived" tag whose value is neither the exact string "true" nor "false". Values are compared case-sensitively as strings before storage, so boolean JSON true, "TRUE", "1", or "yes" are all rejected.
Source
Thrown at crates/buzz-relay/src/handlers/side_effects.rs:519
"ttl",
];
let has_recognized = event
.tags
.iter()
.any(|t| RECOGNIZED_TAGS.contains(&t.kind().to_string().as_str()));
if !has_recognized {
return Err(anyhow::anyhow!(
"kind:9002 must include at least one metadata tag (name, about, archived, topic, purpose, visibility, ttl)"
));
}
// Validate archived values before storage.
for t in event.tags.iter() {
if t.kind().to_string() == "archived" {
match t.content() {
Some("true") | Some("false") => {}
Some(v) => {
return Err(anyhow::anyhow!(
"invalid archived value: {v} (must be \"true\" or \"false\")"
));
}
None => {
return Err(anyhow::anyhow!("archived tag must have a value"));
}
}
}
}
// Validate channel names before storage. A name made entirely of
// display-prefix hashes becomes empty after canonicalization.
for t in event.tags.iter() {
if t.kind().to_string() == "name" {
match t.content() {
Some(v)
if !buzz_core::channel::canonical_channel_name(v)
.trim()View on GitHub (pinned to f956e6fe06)
Solutions
- Send the lowercase string "true" or "false" as the tag value: ["archived", "false"].
- If your data model stores booleans, convert explicitly at serialization: value ? "true" : "false".
- Lint event payloads for archived tag values matching /^(true|false)$/ before publish.
Example fix
// before
{ kind: 9002, tags: [["h", ch], ["archived", isArchived ? 1 : 0]] }
// after
{ kind: 9002, tags: [["h", ch], ["archived", isArchived ? "true" : "false"]] } Defensive patterns
Strategy: type-guard
Validate before calling
// Normalize booleans to the exact relay enum before publish
function archivedTag(value: boolean): string[] {
return ["archived", value ? "true" : "false"];
} Type guard
function isValidArchivedValue(v: string): boolean {
return v === "true" || v === "false";
}
// fail fast before publishing
for (const t of tags.filter((t) => t[0] === "archived")) {
if (!isValidArchivedValue(t[1] ?? "")) throw new Error(`archived must be "true" or "false", got ${t[1]}`);
} Try / catch
try {
await sdk.publish(editEvent);
} catch (e) {
if (String(e).includes("invalid archived value")) {
form.setError("archived", "Must be exactly true or false (lowercase)");
} else throw e;
} Prevention
- Never serialize native booleans or 0/1 into tag values — convert at the boundary.
- Watch for locale-specific capitalization (Python str(True) → "True") in generated payloads.
- Centralize tag-value encoders in one module instead of ad-hoc literals.
When it happens
Trigger: Publishing [["archived", "True"], ["archived", "1"], or ["archived", true]] in a kind:9002 event. Note a JSON boolean true serializes to a missing/None content in some tag encoders and can instead surface as the 'must have a value' error.
Common situations: Clients mapping a UI toggle to a native boolean or an integer 0/1; language differences (Python 'True' capitalization leaking into payloads); copy-pasted payloads from APIs that use 0/1 flags.
Related errors
- invalid visibility value: {v} (must be "open" or "private")
- kind:9002 must include at least one metadata tag (name, abou
- archived tag must have a value
- channel name is required
- visibility tag must have a value
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/845f8b08c72e487c.
Report an issue: GitHub.