gastownhall/beads · error

invalid metadata: %w

Error message

invalid metadata: %w

What it means

This error wraps failures from NormalizeMetadataValue and validateMetadataIfConfigured during an issue update whose updates map contains a "metadata" key. It means the metadata value supplied is not valid JSON, cannot be normalized to a canonical form, or violates configured metadata validation policy. The underlying wrapped error tells which stage failed.

Source

Thrown at internal/storage/dolt/issues.go:175

	})
	if err != nil {
		return nil, err
	}
	return s.GetIssue(ctx, id)
}

// validateUpdateMetadata validates an inbound metadata update value against the
// configured schema (GH#1416 Phase 2) before any wisp routing. It is a no-op
// when the update carries no "metadata" key. Shared by UpdateIssue and
// UpdateIssueChecked so both apply the identical pre-write validation.
func validateUpdateMetadata(updates map[string]interface{}) error {
	rawMeta, ok := updates["metadata"]
	if !ok {
		return nil
	}
	metadataStr, err := storage.NormalizeMetadataValue(rawMeta)
	if err != nil {
		return fmt.Errorf("invalid metadata: %w", err)
	}
	return validateMetadataIfConfigured(json.RawMessage(metadataStr))
}

// checkExpectedVersionInTx enforces the optional ExpectedVersion CAS
// precondition inside tx: when expectedVersion is non-nil the row's current
// RowVersion (row_lock) must still equal it, else the caller's transaction
// returns storage.ErrVersionMismatch and rolls back with the issue unchanged. A
// nil expectedVersion disables the check (an unconditional update).
func checkExpectedVersionInTx(ctx context.Context, tx *sql.Tx, id string, expectedVersion *int64) error {
	if expectedVersion == nil {
		return nil
	}
	return issueops.CheckVersionInTx(ctx, tx, id, *expectedVersion)
}

// UpdateIssue updates fields on an issue.
// Delegates SQL work to issueops.UpdateIssueInTx; handles Dolt-specific concerns

View on GitHub (pinned to 71377f2769)

Solutions

  1. Print the raw metadata string being passed and validate it with a JSON parser (jq) before calling update
  2. Re-run the update with properly quoted JSON, e.g. bd update bd-1 --metadata='{"key":"value"}' or use --metadata=- with stdin
  3. If validation is configured, check the metadata against the configured schema and fix the offending fields
  4. If the stored value is corrupt, read the current metadata, fix it locally, and rewrite it in one update

Example fix

// before
bd update bd-42 --metadata=key:value
// after
bd update bd-42 --metadata='{"key":"value"}'
Defensive patterns

Strategy: validation

Validate before calling

const meta = '{"priority":1}';
if (!/^[\s\S]*$/.test(meta)) throw new Error("empty");
try { JSON.parse(meta); } catch (e) { throw new Error(`metadata is not valid JSON: ${e.message}`); }

Type guard

function isJSONObject(v) {
  if (typeof v !== "string") return false;
  try { const p = JSON.parse(v); return p !== null && typeof p === "object" && !Array.isArray(p); } catch { return false; }
}

Try / catch

try {
  await bd.update(id, { metadata });
} catch (e) {
  if (String(e.message).includes("invalid metadata")) {
    console.error("Metadata rejected:", e.cause ?? e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling updateIssue/updateIssueChecked (e.g. via bd update) with updates["metadata"] set to a non-JSON string, malformed JSON, or metadata that fails schema validation when validation is configured.

Common situations: Shell quoting mangles JSON (single vs double quotes), passing a bare string instead of a JSON object, partial writes by scripts, or enabling metadata validation rules that existing metadata no longer satisfies.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/51e31c7de631f4eb. Report an issue: GitHub.