{"record":{"id":"d5542b0e46a2b1ea","repo":"googleapis/mcp-toolbox","slug":"missing-required-secure-parameter-q-in-secureargu","errorCode":null,"errorMessage":"missing required secure parameter %q in secureArguments","messagePattern":"missing required secure parameter %q in secureArguments","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/server/mcp/v20260728/method.go","lineNumber":910,"sourceCode":"\t\t}\n\t}\n\n\t// Validate that non-secure parameters are not passed in secureArguments (Protocol error)\n\tfor argName := range req.Params.SecureArguments {\n\t\tif !secureParamMap[argName] {\n\t\t\treturn nil, nil, fmt.Errorf(\"parameter %q is not secure and must not be passed in secureArguments\", argName)\n\t\t}\n\t}\n\n\t// Validate that required secure parameters are present in secureArguments (Protocol error)\n\tfor _, p := range paramDefs {\n\t\tif p != nil && p.GetSecure() {\n\t\t\tname := p.GetName()\n\t\t\tif p.GetValueFromParam() == \"\" {\n\t\t\t\tif _, bound := urlParams[name]; !bound {\n\t\t\t\t\tif parameters.CheckParamRequired(p.GetRequired(), p.GetDefault()) {\n\t\t\t\t\t\tif req.Params.SecureArguments == nil {\n\t\t\t\t\t\t\treturn nil, nil, fmt.Errorf(\"missing required secure parameter %q in secureArguments\", name)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif _, ok := req.Params.SecureArguments[name]; !ok {\n\t\t\t\t\t\t\treturn nil, nil, fmt.Errorf(\"missing required secure parameter %q in secureArguments\", name)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge standard arguments and secure arguments.\n\ttoolArgument := make(map[string]any)\n\tmaps.Copy(toolArgument, req.Params.Arguments)\n\tmaps.Copy(toolArgument, req.Params.SecureArguments)\n\n\treturn toolArgument, nil, nil\n}\n","sourceCodeStart":892,"sourceCodeEnd":928,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/server/mcp/v20260728/method.go#L892-L928","documentation":"The tool defines a required secure parameter that gets its value from the request (valueFromParam is empty) and it is not bound by any URL parameter. When the request has no secureArguments object at all, the required secure value is missing, so a protocol error is raised naming the parameter.","triggerScenarios":"A tools/call to a tool whose params include a required secure parameter (secure: true, required: true or required-by-default with no default), where the request omits params.secureArguments entirely, and the parameter is not supplied via URL params.","commonSituations":"Older clients without the com.google.cloud/toolbox.v1 extension never populate secureArguments; server config added a new required secure parameter that the client doesn't know about; agent invocation template omits the secure argument.","solutions":["Add params.secureArguments containing the required parameter, e.g. {\"api_key\": \"...\"}","Have the user provide the value via the secure parameter prompt/flow so the client populates secureArguments","Bind the value as a URL parameter if the deployment supports it (urlParams), e.g. pass it in the server's authenticated endpoint query","Add a default to the parameter in tools.yaml so it is no longer required, or mark it not required"],"exampleFix":"// before\n{\"method\": \"tools/call\", \"params\": {\"name\": \"run_query\", \"arguments\": {\"sql\": \"SELECT 1\"}}}\n// after\n{\"method\": \"tools/call\", \"params\": {\"name\": \"run_query\", \"arguments\": {\"sql\": \"SELECT 1\"}, \"secureArguments\": {\"api_key\": \"<key>\"}}}","handlingStrategy":"validation","validationCode":"const requiredSecure = toolParams.filter(p => p.secure && p.required && p.default === undefined && !p.valueFromParam && !boundUrlParams.has(p.name));\nif (!req.secureArguments && requiredSecure.length) {\n  throw new Error(`secureArguments required for: ${requiredSecure.map(p => p.name).join(', ')}`);\n}","typeGuard":"function hasRequiredSecureArgs(req, requiredSecure) {\n  return requiredSecure.every(p => req.secureArguments && p.name in req.secureArguments);\n}","tryCatchPattern":"try {\n  await mcp.toolsCall({ name: tool, arguments: args, secureArguments: secureArgs });\n} catch (e) {\n  if (/missing required secure parameter/.test(e.message)) {\n    const name = e.message.match(/parameter \"([^\"]+)\"/)?.[1];\n    const value = await promptUserForSecret(name);\n    return mcp.toolsCall({ name: tool, arguments: args, secureArguments: { ...secureArgs, [name]: value } });\n  } else { throw e; }\n}","preventionTips":["Pre-check required secure parameters from the tool manifest and prompt for them before invoking","Always send a secureArguments object (even empty) when the tool declares secure params","Surface the secure-parameter input UI to end users rather than silently omitting","Watch for new required secure parameters added in tools.yaml updates"],"tags":["mcp","security","missing-parameter","secure-parameters"],"backgroundTag":"missing-required-argument","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}