{"record":{"id":"bb918e554f4be356","repo":"plandex-ai/plandex","slug":"invalid-json-w","errorCode":null,"errorMessage":"invalid json: %w","messagePattern":"invalid json: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/schema/schemas.go","lineNumber":50,"sourceCode":"\tsource string\n\tfs     embed.FS\n}\n\nfunc ValidateModelsInputJSON(jsonData []byte) (shared.ClientModelsInput, error) {\n\treturn validateJSON[shared.ClientModelsInput](jsonData, SchemaPathInputConfig)\n}\n\nfunc ValidateModelPackInlineJSON(jsonData []byte) (shared.ClientModelPackSchemaRoles, error) {\n\treturn validateJSON[shared.ClientModelPackSchemaRoles](jsonData, SchemaPathModelPackInline)\n}\n\nfunc validateJSON[T any](jsonData []byte, schemaPath SchemaPath) (T, error) {\n\tvar zero T\n\n\t// strip meta-keywords that break additionalProperties ──\n\tvar tmp interface{}\n\tif err := json.Unmarshal(jsonData, &tmp); err != nil {\n\t\treturn zero, fmt.Errorf(\"invalid json: %w\", err)\n\t}\n\tif obj, ok := tmp.(map[string]interface{}); ok {\n\t\tdelete(obj, \"$schema\") // ignore top-level $schema\n\t\tvar err error\n\t\tjsonData, err = json.Marshal(obj)\n\t\tif err != nil {\n\t\t\treturn zero, fmt.Errorf(\"error marshalling json: %w\", err)\n\t\t}\n\t}\n\n\tschemaLoader := newEmbeddedSchemaLoader(schemaPath)\n\tdocumentLoader := gojsonschema.NewBytesLoader(jsonData)\n\n\tresult, err := gojsonschema.Validate(schemaLoader, documentLoader)\n\tif err != nil {\n\t\treturn zero, err\n\t}\n\tif !result.Valid() {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/schema/schemas.go#L32-L68","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nmodelsJson := []byte(\"{\\\"model\\\": \\\"gpt-4\\\",}\") // trailing comma\n// after\nmodelsJson := []byte(\"{\\\"model\\\": \\\"gpt-4\\\"}\")","handlingStrategy":"validation","validationCode":"func isProbablyJSON(b []byte) error {\n    trimmed := bytes.TrimSpace(bytes.TrimPrefix(bytes.TrimSpace(b), []byte(\"```json\")))\n    trimmed = bytes.TrimSuffix(trimmed, []byte(\"```\"))\n    var v interface{}\n    return json.Unmarshal(trimmed, &v)\n}","typeGuard":"func isJSONObject(b []byte) bool {\n    var m map[string]interface{}\n    return json.Unmarshal(b, &m) == nil\n}","tryCatchPattern":"err := ValidateModelsInputJSON(data)\nif err != nil && strings.HasPrefix(err.Error(), \"invalid json:\") {\n    // surface syntax error with byte offset from wrapped json.SyntaxError\n    var se *json.SyntaxError\n    if errors.As(err, &se) {\n        log.Printf(\"JSON syntax error at offset %d\", se.Offset)\n    }\n}","preventionTips":["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"],"tags":["json","validation","parsing"],"backgroundTag":"invalid-json","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}