Runbook: Empty Recommendations¶
Use this when POST /v1/recommend succeeds but returns no items, or fewer items than expected.
Fast triage¶
Set the local defaults:
BASE_URL=${BASE_URL:-http://localhost:8000}
TENANT_ID=${TENANT_ID:-demo}
SURFACE=${SURFACE:-home}
Validate the request shape before debugging data:
curl -fsS "$BASE_URL/v1/recommend/validate" \
-H "Content-Type: application/json" \
-H "X-Org-Id: $TENANT_ID" \
-H "X-Dev-User-Id: local-dev" \
-H "X-Dev-Org-Id: $TENANT_ID" \
-d "{\"surface\":\"$SURFACE\",\"k\":10,\"user\":{\"anonymous_id\":\"debug-user\"}}"
Then call recommend and keep the full response for the incident record:
curl -fsS "$BASE_URL/v1/recommend" \
-H "Content-Type: application/json" \
-H "X-Org-Id: $TENANT_ID" \
-H "X-Dev-User-Id: local-dev" \
-H "X-Dev-Org-Id: $TENANT_ID" \
-d "{\"surface\":\"$SURFACE\",\"k\":10,\"user\":{\"anonymous_id\":\"debug-user\"}}"
Preserve meta.request_id, meta.config_version, meta.rules_version, and warnings.
Decision flow¶
- If validation fails, fix request shape first. Empty results from an invalid payload are not a ranking incident.
- If
warningsincludesCANDIDATES_INCLUDE_EMPTY, remove or correctcandidates.include_ids. - If
warningsincludesCONSTRAINTS_FILTERED, relax required tags, forbidden tags, or per-tag caps. - If
warningsincludesSIGNAL_UNAVAILABLEorSIGNAL_PARTIAL, check the data mode: - DB-only mode: confirm source tables contain signal rows for the tenant and surface.
- Artifact mode: check the current manifest and artifact object paths.
- If there are no useful warnings, inspect tenant config, tenant rules, and service logs by request ID.
Common causes¶
| Cause | Check | Remediation |
|---|---|---|
| Surface mismatch | The request uses home, but signals were written under another namespace. | Align the integration surface with data production. |
| Candidate allow-list removed everything | Response warning is CANDIDATES_INCLUDE_EMPTY. | Remove the allow-list or use known-good item IDs. |
| Constraints removed everything | Response warning is CONSTRAINTS_FILTERED. | Relax constraints and retry with small k. |
| Missing signal data | Response warning is SIGNAL_UNAVAILABLE or SIGNAL_PARTIAL. | Rebuild or republish the missing signal, or disable the unavailable signal in config. |
| Bad rules/config rollout | Versions changed recently and empty results started afterward. | Roll back config or rules with Rollback Config and Rules. |
Verification¶
After remediation:
- Repeat the same recommendation request.
- Confirm
itemsis non-empty for the affected tenant and surface. - Confirm
warningsno longer identify the root cause. - Keep the before/after response metadata in the incident record.