{"record":{"id":"5807cb2f4b9bc6be","repo":"multica-ai/multica","slug":"remote-server-missing-required-field-url","errorCode":null,"errorMessage":"remote server missing required field `url`","messagePattern":"remote server missing required field `url`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/pkg/agent/opencode_mcp.go","lineNumber":241,"sourceCode":"\tswitch typeStr {\n\tcase \"local\":\n\t\tvar entry opencodeMCPLocal\n\t\tif err := strictDecode(raw, &entry); err != nil {\n\t\t\treturn nil, wrap(err)\n\t\t}\n\t\tif len(entry.Command) == 0 {\n\t\t\treturn nil, wrap(errors.New(\"local server missing required field `command`\"))\n\t\t}\n\t\tif entry.Timeout != nil && *entry.Timeout <= 0 {\n\t\t\treturn nil, wrap(fmt.Errorf(\"`timeout` must be a positive integer, got %d\", *entry.Timeout))\n\t\t}\n\tcase \"remote\":\n\t\tvar entry opencodeMCPRemote\n\t\tif err := strictDecode(raw, &entry); err != nil {\n\t\t\treturn nil, wrap(err)\n\t\t}\n\t\tif entry.URL == \"\" {\n\t\t\treturn nil, wrap(errors.New(\"remote server missing required field `url`\"))\n\t\t}\n\t\tif entry.Timeout != nil && *entry.Timeout <= 0 {\n\t\t\treturn nil, wrap(fmt.Errorf(\"`timeout` must be a positive integer, got %d\", *entry.Timeout))\n\t\t}\n\t\tif len(entry.OAuth) > 0 {\n\t\t\tif err := validateOpenCodeOAuth(entry.OAuth); err != nil {\n\t\t\t\treturn nil, wrap(fmt.Errorf(\"`oauth`: %w\", err))\n\t\t\t}\n\t\t}\n\tcase \"\":\n\t\t// No `type` field. The bare `{\"enabled\": bool}` override shape\n\t\t// is OpenCode's third native variant; anything else without a\n\t\t// type is a malformed local/remote attempt. Surface a single\n\t\t// friendly \"missing type\" error instead of the strict-decode\n\t\t// \"json: unknown field\" leak — the user usually didn't realise\n\t\t// they were mis-using the override shape.\n\t\tvar entry opencodeMCPEnabledOnly\n\t\tif err := strictDecode(raw, &entry); err != nil || entry.Enabled == nil {","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/pkg/agent/opencode_mcp.go#L223-L259","documentation":"Returned when a mcp_config entry declares \"type\": \"remote\" but the strict-decoded object has an empty `url` field. Remote servers are addressed purely by URL, so it is mandatory. If `url` is present, the same branch also validates `timeout` (must be positive when set) and `oauth` (validated by validateOpenCodeOAuth), so those errors come from the same code path.","triggerScenarios":"Setting {\"type\": \"remote\"} (or with \"url\": \"\") for a server in mcp_config; putting the URL under a misspelled key such as \"endpoint\" or \"uri\" that strict decoding would reject, or omitting it entirely.","commonSituations":"Copy-pasting a remote MCP server config that uses a different key name; a templating step that renders an empty URL; intending a local stdio server but selecting \"remote\" by mistake.","solutions":["Add \"url\": \"https://your-mcp-host/sse\" (non-empty string) to the remote entry.","Confirm the key is exactly `url` and the value is a full URL string.","If the server is actually a local stdio process, switch to \"type\": \"local\" with a `command` array instead."],"exampleFix":"// before\n\"mcp_config\": { \"github\": { \"type\": \"remote\", \"endpoint\": \"https://mcp.github.com/sse\" } }\n\n// after\n\"mcp_config\": { \"github\": { \"type\": \"remote\", \"url\": \"https://mcp.github.com/sse\" } }","handlingStrategy":"validation","validationCode":"function validateRemoteEntry(e: { type: string; url?: unknown }): string | null {\n  if (e.type === 'remote' && (typeof e.url !== 'string' || e.url === '')) {\n    return 'remote MCP server requires a non-empty `url`';\n  }\n  return null;\n}","typeGuard":"function isRemoteMCPEntry(e: Record<string, unknown>): e is { type: 'remote'; url: string; timeout?: number; oauth?: Record<string, unknown> } {\n  return e.type === 'remote' && typeof e.url === 'string' && e.url.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Construct remote entries from a single URL constant so the key is never misspelled.","Validate URLs with new URL(...) at authoring time to catch template/rendering mistakes."],"tags":["config","mcp","validation","opencode","remote-server"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}