gastownhall/beads · error
unsupported value %T for update field %q
Error message
unsupported value %T for update field %q
What it means
buildUpdatePatch (cmd/bd/update.go) recognizes a field key but the supplied value has the wrong Go type (the type assertion like value.(bool) fails), so the field is marked not-ok and this error reports the offending %T and field name. It fires when programmatic callers (or proxied JSON payloads decoded into interface{}) pass, say, a string where a bool or int is required.
Source
Thrown at cmd/bd/update.go:754
patch.Metadata.Set = set
}
case storageissueops.OpUnsetMetadata:
patch.Metadata.Unset, ok = value.([]string)
case "wisp":
var flag bool
if flag, ok = value.(bool); ok {
wisp = &flag
}
case "no_history":
var flag bool
if flag, ok = value.(bool); ok {
noHistory = &flag
}
default:
return issueops.IssuePatch{}, fmt.Errorf("unsupported update field %q", key)
}
if !ok {
return issueops.IssuePatch{}, fmt.Errorf("unsupported value %T for update field %q", value, key)
}
}
// --ephemeral/--persistent/--no-history/--history select one complete
// persistence state. The flag parsing already rejects the contradictory
// pairs; the remaining combinations resolve most-specific-first, which
// reproduces the column pairs the old two-boolean write produced.
switch {
case wisp != nil && *wisp:
patch.Persistence = setField(issueops.PersistenceModeEphemeral)
case noHistory != nil && *noHistory:
patch.Persistence = setField(issueops.PersistenceModeNoHistory)
case wisp != nil || noHistory != nil:
patch.Persistence = setField(issueops.PersistenceModePersistent)
}
return patch, nil
}
func stringField(value any) (issueops.Field[string], bool) {View on GitHub (pinned to 71377f2769)
Solutions
- Send the value with the expected type: true/false (not "true") for boolean fields like no_history, numbers unquoted for numeric fields
- Fix the client script to build the payload with native types (e.g. use jq --argjson or language-native JSON encoders)
- Check buildUpdatePatch's switch for the exact expected Go type per field and cast/convert before calling
- If a type legitimately changed between versions, update the proxy/client to the matching bd version
Example fix
// before
payload := `{"no_history": "true"}`
// after
payload := `{"no_history": true}` Defensive patterns
Strategy: type-guard
Validate before calling
func checkValueTypes(fields map[string]any) error {
for k, v := range fields {
switch k {
case "no_history", "ephemeral", "persistent":
if _, ok := v.(bool); !ok {
return fmt.Errorf("field %q must be bool, got %T", k, v)
}
}
}
return nil
} Type guard
func asBool(v any) (bool, bool) {
b, ok := v.(bool)
return b, ok
} Try / catch
patch, err := buildUpdatePatch(fields)
if err != nil {
if strings.Contains(err.Error(), "unsupported value") {
// coerce common string→native conversions and retry once
}
return err
} Prevention
- Use typed structs (not map[string]any) when constructing update payloads in Go
- In JSON, never quote booleans or numbers; use jq --argjson / --jsonargs for raw values
- Add schema validation (e.g. JSON Schema) on proxy update endpoints before calling buildUpdatePatch
- Write round-trip tests asserting each field's expected Go type
When it happens
Trigger: Sending {"no_history": "true"} (string) instead of true (bool) in an update payload; a scripting wrapper marshaling numbers as strings; a proxy client serializing enum-like values as strings where the switch expects a typed value.
Common situations: JSON APIs where values arrive as interface{} — JSON has no distinct bool/int typing guarantees if produced loosely; shell scripts building payloads with quoted values; version drift where a field's type changed.
Related errors
- unsupported update field %q
- %s
- line %d (%s): %w
- line %d: %w
- %w. Hint: run 'bd init' to create a database in the current
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5b9d5dd66c2eae09.
Report an issue: GitHub.