{"record":{"id":"aadde64cf2278eb0","repo":"SigNoz/signoz","slug":"codelicenseunavailable-aadde6","errorCode":"CodeLicenseUnavailable","errorMessage":"a valid license is not available","messagePattern":"a valid license is not available","errorType":"error_code","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"ee/modules/cloudintegration/implcloudintegration/module.go","lineNumber":66,"sourceCode":"\t\tstore:             store,\n\t\tdashboardModule:   dashboardModule,\n\t\tglobal:            global,\n\t\tzeus:              zeus,\n\t\tgateway:           gateway,\n\t\tlicensing:         licensing,\n\t\tserviceAccount:    serviceAccount,\n\t\tcloudProvidersMap: cloudProvidersMap,\n\t\tconfig:            config,\n\t}, nil\n}\n\n// GetConnectionCredentials returns credentials required to generate connection artifact. eg. apiKey, ingestionKey etc.\n// It will return creds it can deduce and return empty value for others.\nfunc (module *module) GetConnectionCredentials(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType) (*cloudintegrationtypes.Credentials, error) {\n\t// get license to get the deployment details\n\tlicense, err := module.licensing.GetActive(ctx, orgID)\n\tif err != nil {\n\t\treturn nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, \"a valid license is not available\").WithAdditional(\"this feature requires a valid license\").WithAdditional(err.Error())\n\t}\n\n\t// get deployment details from zeus, ignore error\n\trespBytes, _ := module.zeus.GetDeployment(ctx, license.Key)\n\n\tvar signozAPIURL string\n\n\tif len(respBytes) > 0 {\n\t\t// parse deployment details, ignore error, if client is asking api url every time check for possible error\n\t\tdeployment, _ := zeustypes.NewGettableDeployment(respBytes)\n\t\tif deployment != nil {\n\t\t\tsignozAPIURL, _ = cloudintegrationtypes.GetSigNozAPIURLFromDeployment(deployment)\n\t\t}\n\t}\n\n\t// ignore error\n\tapiKey, _ := module.getOrCreateAPIKey(ctx, orgID, provider)\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/ee/modules/cloudintegration/implcloudintegration/module.go#L48-L84","documentation":"parseGetErrorRequest requires the groupID query parameter when fetching a single error from the errors API; an empty/missing groupID yields 'groupID param cannot be empty from the query'. Used by getErrorFromErrorID, getNextPrevErrorIDs and getErrorFromGroupID handlers.","triggerScenarios":"GET /api/v1/errors/{errorID-or-group} (or the next/prev endpoint) with a valid ts= timestamp but no groupID= parameter, or groupID= with an empty value.","commonSituations":"Frontend deep links losing the groupID query string on refresh; clients passing only errorID assuming it identifies the group; URL encoding bugs stripping empty params; API wrappers that omit optional-looking params.","solutions":["Always include groupID=<groupID> (from the errors list response's groupID field) in the request","Persist both errorID and groupID when building deep links","Validate presence of groupID client-side before fetching error detail"],"exampleFix":"# before\ncurl '.../api/v1/errors/view?ts=1700000000000000000&errorID=abc'\n\n# after\ncurl '.../api/v1/errors/view?ts=1700000000000000000&groupID=xyz&errorID=abc'","handlingStrategy":"validation","validationCode":"groupID := r.URL.Query().Get(\"groupID\")\nif strings.TrimSpace(groupID) == \"\" {\n\treturn errors.New(\"groupID is required; take it from the errors list response\")\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Persist groupID with deep links","Always read groupID from the list-error payload","Validate required params in a shared URL builder"],"tags":["signoz","errors-api","api-params","group-id","validation"],"backgroundTag":"missing-required-query-param","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}