{"record":{"id":"5c127529c40e0a0b","repo":"GoogleCloudPlatform/microservices-demo","slug":"product-id-not-specified","errorCode":null,"errorMessage":"product id not specified","messagePattern":"product id not specified","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"src/frontend/handlers.go","lineNumber":148,"sourceCode":"\t\tplat.provider = \"Azure\"\n\t\tplat.css = \"azure-platform\"\n\t} else if env == \"gcp\" {\n\t\tplat.provider = \"Google Cloud\"\n\t\tplat.css = \"gcp-platform\"\n\t} else if env == \"alibaba\" {\n\t\tplat.provider = \"Alibaba Cloud\"\n\t\tplat.css = \"alibaba-platform\"\n\t} else {\n\t\tplat.provider = \"local\"\n\t\tplat.css = \"local\"\n\t}\n}\n\nfunc (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tid := mux.Vars(r)[\"id\"]\n\tif id == \"\" {\n\t\trenderHTTPError(log, r, w, errors.New(\"product id not specified\"), http.StatusBadRequest)\n\t\treturn\n\t}\n\tlog.WithField(\"id\", id).WithField(\"currency\", currentCurrency(r)).\n\t\tDebug(\"serving product page\")\n\n\tp, err := fe.getProduct(r.Context(), id)\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve product\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tcurrencies, err := fe.getCurrencies(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve currencies\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tcart, err := fe.getCart(r.Context(), sessionID(r))\n\tif err != nil {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/frontend/handlers.go#L130-L166","documentation":"The frontend productHandler requires a product id from the URL route variable. If the id captured by the mux route is empty, it renders a 400 Bad Request page with 'product id not specified' instead of trying to fetch the product.","triggerScenarios":"An HTTP GET to /product/ with an empty id segment, a rewritten/proxied URL that drops the {id} path variable, or a stale link pointing at /product without an id.","commonSituations":"Broken or hand-edited product links in emails/marketing; reverse-proxy rewrite rules mangling the path; users bookmarking a truncated URL; templates generating hrefs with an empty id.","solutions":["Fix the source of the request: ensure the URL is /product/<valid-id>","Check reverse proxy/rewrite rules preserve the id path segment","Validate/guard links in templates that render product hrefs","Return a friendlier 404/redirect from productHandler for empty ids"],"exampleFix":"<!-- before -->\n<a href=\"/product/\">View</a>\n<!-- after -->\n<a href=\"/product/{{.Item.Id}}\">View</a>","handlingStrategy":"validation","validationCode":"// client-side link check before navigating\nconst id = new URL(url).pathname.split('/').pop();\nif (!id) { console.warn('product link missing id:', url); return; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate product hrefs in templates render a non-empty id","Test routes /product/{id} end-to-end including behind reverse proxies","Return a friendly 404 page for missing ids instead of a bare 400","Monitor logs for repeated 'product id not specified' to find broken link sources"],"tags":["http","frontend","request-validation","go"],"backgroundTag":"missing-path-parameter","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}