SigNoz/signoz · error · errors.Error
CodeLicenseUnavailable
CodeLicenseUnavailable
Error message
a valid license is not available
What it means
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.
Source
Thrown at ee/modules/cloudintegration/implcloudintegration/module.go:66
store: store,
dashboardModule: dashboardModule,
global: global,
zeus: zeus,
gateway: gateway,
licensing: licensing,
serviceAccount: serviceAccount,
cloudProvidersMap: cloudProvidersMap,
config: config,
}, nil
}
// GetConnectionCredentials returns credentials required to generate connection artifact. eg. apiKey, ingestionKey etc.
// It will return creds it can deduce and return empty value for others.
func (module *module) GetConnectionCredentials(ctx context.Context, orgID valuer.UUID, provider cloudintegrationtypes.CloudProviderType) (*cloudintegrationtypes.Credentials, error) {
// get license to get the deployment details
license, err := module.licensing.GetActive(ctx, orgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
// get deployment details from zeus, ignore error
respBytes, _ := module.zeus.GetDeployment(ctx, license.Key)
var signozAPIURL string
if len(respBytes) > 0 {
// parse deployment details, ignore error, if client is asking api url every time check for possible error
deployment, _ := zeustypes.NewGettableDeployment(respBytes)
if deployment != nil {
signozAPIURL, _ = cloudintegrationtypes.GetSigNozAPIURLFromDeployment(deployment)
}
}
// ignore error
apiKey, _ := module.getOrCreateAPIKey(ctx, orgID, provider)
View on GitHub (pinned to 5069bf80b0)
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
Example fix
# before curl '.../api/v1/errors/view?ts=1700000000000000000&errorID=abc' # after curl '.../api/v1/errors/view?ts=1700000000000000000&groupID=xyz&errorID=abc'
Defensive patterns
Strategy: validation
Validate before calling
groupID := r.URL.Query().Get("groupID")
if strings.TrimSpace(groupID) == "" {
return errors.New("groupID is required; take it from the errors list response")
} Type guard
null
Try / catch
null
Prevention
- Persist groupID with deep links
- Always read groupID from the list-error payload
- Validate required params in a shared URL builder
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/aadde64cf2278eb0.
Report an issue: GitHub.