multica-ai/multica · error
entry must be a JSON object
Error message
entry must be a JSON object
What it means
Thrown by validateOpenCodeNativeMCPEntry when a per-server entry in the agent's opencode mcp_config is not a JSON object. The validator's discriminator probe and strict decoders assume an object, so a primitive (string, number, array, null, or empty raw) is rejected up front with this clear message instead of a confusing decoder error. The message is wrapped as `opencode mcp_config: server "<name>": ...`.
Source
Thrown at server/pkg/agent/opencode_mcp.go:203
// validateOpenCodeNativeMCPEntry strict-decodes one native-shape entry
// against OpenCode's schema and returns the equivalent map[string]any
// representation. The decode is intentionally strict
// (DisallowUnknownFields) — any field outside the McpLocalConfig /
// McpRemoteConfig / `{enabled: bool}` shapes is rejected, matching the
// schema's `additionalProperties: false` and surfacing user typos as
// errors before they reach OpenCode.
func validateOpenCodeNativeMCPEntry(name string, raw json.RawMessage) (map[string]any, error) {
wrap := func(err error) error {
return fmt.Errorf("opencode mcp_config: server %q: %w", name, err)
}
// JSON-object guard: the discriminator probe and strict decoders
// below assume an object; without this guard a primitive (string,
// number, array, null) would surface a confusing decoder error.
trimmed := bytes.TrimSpace(raw)
if len(trimmed) == 0 || trimmed[0] != '{' {
return nil, wrap(errors.New("entry must be a JSON object"))
}
// Discriminator probe: peek `type` to choose the right strict
// decode target. This first decode is intentionally permissive so
// "type: 5" surfaces a clear "type must be a string" error rather
// than the strict-decode generic "json: cannot unmarshal number".
var probe struct {
Type *json.RawMessage `json:"type,omitempty"`
}
if err := json.Unmarshal(raw, &probe); err != nil {
return nil, wrap(fmt.Errorf("parse: %w", err))
}
var typeStr string
if probe.Type != nil {
if err := json.Unmarshal(*probe.Type, &typeStr); err != nil {
return nil, wrap(fmt.Errorf("`type` must be a string, got %s", strings.TrimSpace(string(*probe.Type))))
}
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Wrap each server entry in a JSON object with an explicit type: {"type":"remote","url":"..."} or {"type":"local","command":[...]}
- Remove null entries for servers you do not want to configure.
- Re-check the OpenCode mcp_config schema for the supported variants (local, remote, bare {"enabled": bool}).
Example fix
// before
"mcp_config": { "github": "https://mcp.github.com/sse" }
// after
"mcp_config": { "github": { "type": "remote", "url": "https://mcp.github.com/sse" } } Defensive patterns
Strategy: type-guard
Validate before calling
// Validate before submitting mcp_config
for name, raw := range mcpConfig {
if !isObject(raw) {
return fmt.Errorf("mcp_config entry %q must be a JSON object", name)
}
} Type guard
function isMCPEntryObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Prevention
- Always author mcp_config entries as objects with an explicit type discriminator.
- Validate the whole mcp_config with the same schema the server uses before saving it in agent settings.
- Never inline command strings or argv arrays directly as the entry value.
When it happens
Trigger: Setting mcp_config.<name> to a scalar or array, e.g. "mcp_config": {"github": "https://mcp.github.com"} or {"github": ["npx", "-y", "server"]} or {"github": null}, via the agent config API or config file.
Common situations: Copying an SSH-style or Claude-style config line (bare command string / argv array) into OpenCode's native mcp_config; YAML/JSON config authoring mistakes; passing a URL string where a {"type":"remote","url":...} object is required.
Related errors
- local server missing required field `command`
- remote server missing required field `url`
- missing required field `type` (must be "local" or "remote",
- config must be a JSON object
- config must not be empty
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/47ec6549df892f13.
Report an issue: GitHub.