plandex-ai/plandex · error
invalid json: %w
Error message
invalid json: %w
What it means
validateJSON first does a preliminary json.Unmarshal into interface{} to strip meta-keywords like top-level $schema. This error means the supplied JSON bytes are syntactically invalid JSON before schema validation can even run.
Source
Thrown at app/cli/schema/schemas.go:50
source string
fs embed.FS
}
func ValidateModelsInputJSON(jsonData []byte) (shared.ClientModelsInput, error) {
return validateJSON[shared.ClientModelsInput](jsonData, SchemaPathInputConfig)
}
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() {View on GitHub (pinned to e2d772072e)
Solutions
- Validate the JSON with a linter/parser (jq . file.json) and fix the syntax error
- Strip markdown code fences and surrounding prose before passing bytes in
- Ensure the file is UTF-8 and not truncated/empty
- Regenerate or re-export the JSON from its source
Example fix
// before
modelsJson := []byte("{\"model\": \"gpt-4\",}") // trailing comma
// after
modelsJson := []byte("{\"model\": \"gpt-4\"}") Defensive patterns
Strategy: validation
Validate before calling
func isProbablyJSON(b []byte) error {
trimmed := bytes.TrimSpace(bytes.TrimPrefix(bytes.TrimSpace(b), []byte("```json")))
trimmed = bytes.TrimSuffix(trimmed, []byte("```"))
var v interface{}
return json.Unmarshal(trimmed, &v)
} Type guard
func isJSONObject(b []byte) bool {
var m map[string]interface{}
return json.Unmarshal(b, &m) == nil
} Try / catch
err := ValidateModelsInputJSON(data)
if err != nil && strings.HasPrefix(err.Error(), "invalid json:") {
// surface syntax error with byte offset from wrapped json.SyntaxError
var se *json.SyntaxError
if errors.As(err, &se) {
log.Printf("JSON syntax error at offset %d", se.Offset)
}
} Prevention
- Lint JSON files before loading them (jq, editor JSON mode)
- Strip markdown code fences from LLM output before validation
- Never hand-edit JSON without re-validating
- Check files are UTF-8 and not empty/truncated
When it happens
Trigger: ValidateModelsInputJSON or ValidateModelPackInlineJSON is called with bytes that fail json.Unmarshal: trailing commas, comments, single quotes, truncated output, or non-JSON text (e.g. an LLM wrapped JSON in markdown fences).
Common situations: Feeding model settings from a hand-edited file with a syntax error; passing LLM-generated JSON that includes ```json fences or trailing text; empty string input.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error unmarshalling JSON file: %v
- error unmarshalling JSON file: %v
- error marshalling json: %w
- error parsing embedded schema %s: %v
- error parsing schema JSON: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/bb918e554f4be356.
Report an issue: GitHub.