{"record":{"id":"ac3f4dbb8080fe9a","repo":"hashicorp/vault","slug":"missing-required-query-params","errorCode":null,"errorMessage":"Missing required query params","messagePattern":"Missing required query params","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/app/routes/vault/cluster/oidc-provider.js","lineNumber":134,"sourceCode":"    const { provider_name, namespace, ...qp } = params;\n    const decodedRedirect = decodeURI(qp.redirect_uri);\n    return {\n      provider_name,\n      qp,\n      decodedRedirect,\n      namespace,\n    };\n  }\n\n  async model(params) {\n    const modelInfo = this._getInfoFromParams(params);\n    const { qp, decodedRedirect, ...routeParams } = modelInfo;\n    const endpoint = this._buildUrl(\n      `${this.win.origin}/v1/identity/oidc/provider/${routeParams.provider_name}/authorize`,\n      qp\n    );\n    if (!qp.redirect_uri) {\n      throw new Error('Missing required query params');\n    }\n    try {\n      const response = await this.auth.ajax(endpoint, 'GET', { namespace: routeParams.namespace });\n      if ('consent' === qp.prompt?.toLowerCase()) {\n        return {\n          consent: {\n            code: response.code,\n            redirect: decodedRedirect,\n            state: qp.state,\n          },\n        };\n      }\n      return this._handleSuccess(response, decodedRedirect, qp.state);\n    } catch (errorRes) {\n      const resp = await errorRes.json();\n      const code = resp.error;\n      // This go-multierror package formats multiple errors as a single string:\n      // https://github.com/hashicorp/go-multierror/blob/main/format.go#L28","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/hashicorp/vault/blob/744b611b5700b3b7f82d76b4d6938a91b9989367/ui/app/routes/vault/cluster/oidc-provider.js#L116-L152","documentation":"Thrown by the OIDC provider route model (ui/app/routes/vault/cluster/oidc-provider.js:134). The route proxies the browser to Vault's identity OIDC provider authorize endpoint; before issuing the GET it mirrors the endpoint's contract by verifying that the request carries a redirect_uri query param and throws if it is absent.","triggerScenarios":"Loading /ui/vault/cluster/oidc-provider/<provider_name>/authorize (or the route's URL shape) without a redirect_uri query parameter, or with it spelled/encoded incorrectly so qp.redirect_uri is undefined.","commonSituations":"A relying party starts the flow without registering a redirect_uri; a hand-crafted or bookmarked authorize URL missing params; params stripped by a proxy or lost during URL encoding.","solutions":["Include a valid redirect_uri (and the usual state/scope params) in the authorize URL: /ui/vault/cluster/oidc-provider/<name>/authorize?redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&...","Ensure the relying party's OIDC client is configured to send redirect_uri","URL-encode all query parameter values"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate required authorize params before entering the provider route\nconst required = ['redirect_uri'];\nconst missing = required.filter((p) => !params[p]);\nif (missing.length) {\n  renderBadRequest(`Missing required query params: ${missing.join(', ')}`);\n  return;\n}","typeGuard":"function hasRedirectUri(qp: Record<string, string | undefined>): qp is { redirect_uri: string } {\n  return typeof qp.redirect_uri === 'string' && qp.redirect_uri.length > 0;\n}","tryCatchPattern":"try {\n  await this.router.transitionTo('vault.cluster.oidc-provider', { queryParams: params });\n} catch (e) {\n  if (e.message === 'Missing required query params') {\n    notifyUser('The authorize URL must include redirect_uri (and should include state)');\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always start flows from a properly configured OIDC client so redirect_uri is populated","URL-encode all query params; stripped/decoded-empty params trip this guard"],"tags":["oidc","query-params","authorization","validation"],"backgroundTag":null,"analyzedSha":"744b611b5700b3b7f82d76b4d6938a91b9989367","analyzedAt":"2026-08-15T14:40:29.333Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}