plandex-ai/plandex · error
error marshalling json: %w
Error message
error marshalling json: %w
What it means
After stripping the top-level $schema key, validateJSON re-marshals the object back to bytes for the schema validator. This error means json.Marshal of the cleaned map failed — extremely rare for map[string]interface{} input derived from valid JSON, but possible with values the encoder cannot handle (e.g. channels, funcs injected programmatically).
Source
Thrown at app/cli/schema/schemas.go:57
func ValidateModelPackInlineJSON(jsonData []byte) (shared.ClientModelPackSchemaRoles, error) {
return validateJSON[shared.ClientModelPackSchemaRoles](jsonData, SchemaPathModelPackInline)
}
func validateJSON[T any](jsonData []byte, schemaPath SchemaPath) (T, error) {
var zero T
// strip meta-keywords that break additionalProperties ──
var tmp interface{}
if err := json.Unmarshal(jsonData, &tmp); err != nil {
return zero, fmt.Errorf("invalid json: %w", err)
}
if obj, ok := tmp.(map[string]interface{}); ok {
delete(obj, "$schema") // ignore top-level $schema
var err error
jsonData, err = json.Marshal(obj)
if err != nil {
return zero, fmt.Errorf("error marshalling json: %w", err)
}
}
schemaLoader := newEmbeddedSchemaLoader(schemaPath)
documentLoader := gojsonschema.NewBytesLoader(jsonData)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
return zero, err
}
if !result.Valid() {
var msgs []string
for _, d := range result.Errors() {
msgs = append(msgs, "• "+d.String())
}
return zero, errors.New(strings.Join(msgs, "\n"))
}
View on GitHub (pinned to e2d772072e)
Solutions
- Ensure the input originates from valid JSON bytes, not raw Go structures
- Check for non-serializable values injected before validation
- Bypass $schema stripping (omit $schema) to skip the re-marshal path
- Report as a bug if input is plain JSON and this still fires
Example fix
// before
input := map[string]interface{}{"cb": func() {}} // unmarshalable
// after
input := []byte(`{"name":"my-pack"}`) // pass JSON bytes Defensive patterns
Strategy: validation
Validate before calling
var probe interface{}
if err := json.Unmarshal(data, &probe); err != nil {
return err
}
// round-trip check catches unmarshalable values early
if _, err := json.Marshal(probe); err != nil {
return fmt.Errorf("round-trip marshal failed: %w", err)
} Type guard
func roundTrips(b []byte) bool {
var v interface{}
if json.Unmarshal(b, &v) != nil { return false }
_, err := json.Marshal(v)
return err == nil
} Try / catch
err := ValidateModelPackInlineJSON(data)
if err != nil && strings.Contains(err.Error(), "error marshalling json") {
// input contained non-encodable values; log and report as a bug
return fmt.Errorf("validation pre-check failed: %w", err)
} Prevention
- Always pass real JSON bytes, not raw Go maps with arbitrary types
- Keep $schema handling to the library (avoid manual mutation)
- Round-trip test unusual inputs before validating
When it happens
Trigger: ValidateModelsInputJSON / ValidateModelPackInlineJSON receiving an object whose re-encoding fails after $schema removal — practically only when unmarshalable values were placed into the parsed structure.
Common situations: Programmatic callers constructing the input map with unsupported Go types; corruption of the decoded value by intermediary processing code.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- error marshalling auth header: %v
- error marshalling models: %v
- error marshalling account credentials: %v
- error unmarshalling JSON file: %v
- error marshalling model pack: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/99a6f967e3edd9a0.
Report an issue: GitHub.