{"record":{"id":"815b2ea1feb2d57a","repo":"JuliusBrussee/caveman","slug":"cacheengine-invalid-scope","errorCode":null,"errorMessage":"cacheengine: invalid scope","messagePattern":"cacheengine: invalid scope","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cacheengine/engine.go","lineNumber":270,"sourceCode":"\tif err != nil {\n\t\treturn Plan{}, err\n\t}\n\treturn Plan{\n\t\tDecision:       DecisionNewEpoch,\n\t\tReason:         string(cacheguard.DecisionNewEpoch),\n\t\tProfileID:      profile.ID,\n\t\tMode:           profile.Mode,\n\t\tAttribution:    profile.Attribution,\n\t\tPrefixSHA256:   result.PrefixSHA256,\n\t\tEconomicsBasis: economicsBasis,\n\t\tKeyShardCount:  1,\n\t\tWarnings:       warnings,\n\t}, nil\n}\n\nfunc validatePlanRequest(request PlanRequest) error {\n\tif !validIdentity(request.Scope, 4096, false) {\n\t\treturn errors.New(\"cacheengine: invalid scope\")\n\t}\n\tif !validIdentity(request.Epoch, 4096, false) {\n\t\treturn errors.New(\"cacheengine: invalid epoch\")\n\t}\n\tif !validIdentity(request.PartitionKey, 4096, true) {\n\t\treturn errors.New(\"cacheengine: invalid partition key\")\n\t}\n\tif request.ExpectedCalls < 0 || request.ExpectedRequestsPerMinute < 0 {\n\t\treturn errors.New(\"cacheengine: negative traffic expectation\")\n\t}\n\tprofile := normalizedProfile(request.Profile)\n\tif !validIdentity(profile.ID, 256, false) || !validIdentity(profile.Provider, 64, true) || !validIdentity(profile.OptimizerID, 256, true) {\n\t\treturn errors.New(\"cacheengine: invalid profile identity\")\n\t}\n\tif profile.Mode != ModeUnsupported && profile.Mode != ModeImplicit && profile.Mode != ModeAffinity && profile.Mode != ModeExplicit {\n\t\treturn fmt.Errorf(\"cacheengine: unknown mode %q\", profile.Mode)\n\t}\n\tif profile.Mode != ModeUnsupported {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/engine.go#L252-L288","documentation":"Returned by validatePlanRequest (used by both Plan and StartEpoch) when validIdentity(request.Scope, 4096, false) fails. Scope is a required, non-optional identity string: it must be non-empty, within 4096 bytes, and pass the identity character/structure rules the validator enforces (partitionKey=false means blank is not allowed). It names the cache scope the request belongs to.","triggerScenarios":"Calling Plan or StartEpoch with an empty Scope, one exceeding 4096 bytes, or containing characters the identity validator rejects (e.g. control characters or invalid UTF-8, per validIdentity's rules).","commonSituations":"Deriving scope from user IDs or URLs without sanitizing/truncating; forgetting to set Scope when building PlanRequest via struct literal; multi-tenant keys concatenating long tenant metadata past 4096 bytes.","solutions":["Set PlanRequest.Scope to a stable, non-empty identifier within 4096 bytes (e.g. 'tenant:42:session:abc' trimmed)","Hash or truncate programmatically derived scopes: use a SHA-256 hex of oversized inputs","Check the other identity fields in the same validator (Epoch, PartitionKey, profile) — they fail with their own messages"],"exampleFix":"// before\nreq := cacheengine.PlanRequest{Epoch: \"e1\"} // Scope left empty\n\n// after\nreq := cacheengine.PlanRequest{Scope: \"tenant:42:chat\", Epoch: \"e1\"}","handlingStrategy":"validation","validationCode":"func safeScope(scope string) string {\n\tif len(scope) > 4096 {\n\t\tsum := sha256.Sum256([]byte(scope))\n\t\treturn hex.EncodeToString(sum[:])\n\t}\n\treturn scope\n}\n\nif strings.TrimSpace(req.Scope) == \"\" {\n\treturn errors.New(\"scope required\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := eng.Plan(req); err != nil {\n\tif err.Error() == \"cacheengine: invalid scope\" {\n\t\treturn fmt.Errorf(\"scope %q invalid; use non-empty <=4096B identifier\", req.Scope)\n\t}\n\treturn Plan{}, err\n}","preventionTips":["Generate Scope from a fixed vocabulary (tenant, app, channel) instead of raw user input","Hash oversized derived scopes to keep them short and stable"],"tags":["go","validation","api-misuse","configuration"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}