gastownhall/beads · error

metadata schema violation: %s

Error message

metadata schema violation: %s

What it means

Issue metadata was rejected by the configured metadata schema. When metadata validation mode is 'enforce' (not 'warn'/'none') and a metadata schema is defined in config, any metadata not conforming (wrong type, missing required field, disallowed enum value, out of min/max range) makes the write fail with the first violation reported.

Source

Thrown at internal/storage/issueops/helpers.go:449

	schemaCfg := storage.MetadataSchemaConfig{
		Mode:   mode,
		Fields: fields,
	}

	errs := storage.ValidateMetadataSchema(metadata, schemaCfg)
	if len(errs) == 0 {
		return nil
	}

	if mode == "warn" {
		for _, e := range errs {
			fmt.Fprintf(os.Stderr, "warning: %s\n", e.Error())
		}
		return nil
	}

	return fmt.Errorf("metadata schema violation: %s", errs[0].Error())
}

// ParseFieldSchema converts a raw config map into a MetadataFieldSchema.
func ParseFieldSchema(m map[string]interface{}) storage.MetadataFieldSchema {
	schema := storage.MetadataFieldSchema{}

	if t, ok := m["type"].(string); ok {
		schema.Type = storage.MetadataFieldType(t)
	}
	if req, ok := m["required"].(bool); ok {
		schema.Required = req
	}

	if vals, ok := m["values"]; ok {
		switch v := vals.(type) {
		case []interface{}:
			for _, item := range v {
				if s, ok := item.(string); ok {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix the metadata payload to satisfy the schema (correct types, include required fields, use allowed values) — the message names the first violation.
  2. If the violation is intentional during migration, set metadata validation mode to 'warn' in config.yaml until callers are updated.
  3. Update the schema in config.yaml if the new metadata shape is the desired contract.
  4. Run validation locally before writing: construct the same schema config and call storage.ValidateMetadataSchema on your metadata JSON to list all violations.

Example fix

// before
metadata := map[string]interface{}{"priority": "high", "owner": "alice"} // priority must be number, owner required? schema says team required
// after
metadata := map[string]interface{}{"priority": 2, "owner": "alice", "team": "core"}
raw, _ := json.Marshal(metadata)
if err := storage.ValidateMetadataSchema(raw, schemaCfg); len(errs) > 0 { fix(errs) }
Defensive patterns

Strategy: validation

Validate before calling

func validateBeforeWrite(metadata map[string]interface{}) error {
    raw, _ := json.Marshal(metadata)
    fields := loadSchemaFieldsFromConfig() // same source bd reads
    cfg := storage.MetadataSchemaConfig{Mode: "error", Fields: fields}
    errs := storage.ValidateMetadataSchema(raw, cfg)
    if len(errs) > 0 { return errors.New(errs[0].Error()) }
    return nil
}

Try / catch

if err := storage.ValidateMetadataIfConfigured(rawMeta); err != nil {
    var retryable bool
    if strings.HasPrefix(err.Error(), "metadata schema violation:") {
        // fix payload per the reported violation, then retry
        return fmt.Errorf("fix metadata: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling bd create/update (ApplyMetadataPatch, PrepareIssueForInsert, metadata merge ops) with issue metadata that violates the schema declared under metadata schema fields in config.yaml, while metadata-validation mode is set to enforce/error.

Common situations: CI automation writing metadata keys with wrong types (string vs number); a teammate tightened the schema and old scripts now fail; required field added to schema but not supplied; enum value renamed in config but still sent by clients.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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