Repository navigation
fix: Hibernating filter in Devtron Apps list shows incomplete results (pager #2974) - #7049
Merged
Merged
Conversation
…nation The Devtron Apps list dropped the entire AppStatuses filter whenever HIBERNATING was among the selected statuses, ran LIMIT/OFFSET and count(distinct a.id) over the *unfiltered* app set, and only then re-applied the status filter in memory -- to the single page that came back -- while overwriting the total count with the size of that surviving slice. So the filter returned just the hibernating apps that happened to land on the requested page of the unfiltered listing, and reported that handful as the grand total, leaving the UI with no further pages. Verified against a customer database: 592 hibernating apps exist, 2 were shown. HIBERNATING is an ordinary value persisted in app_status.status (appStatus.UpdateStatusWithAppIdEnvId normalises Suspended/Hibernated to it), and the in-memory pass compared against that very same column -- so the predicate was always expressible in SQL. buildAppListingWhereCondition already emits `aps.status IN (?)` for any status list, including the NOT DEPLOYED combination, so the workaround is simply removed rather than replaced. This also fixes combination filters that were collateral damage: selecting Healthy + Hibernating blanked both predicates, and Hibernating + Not Deployed additionally killed the NOT DEPLOYED SQL branch. The workaround was originally added for Helm-type pipelines, whose status is not persisted in app_status. That cohort is unaffected either way -- the in-memory pass read the same empty column -- and is now documented as a TODO in place of the removed code. Pager: devtron-labs/sprint-tasks#2974 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Shivam-nagar23
requested review from
prakarsh-dt and
vivek-devtron
as code owners
September 22, 2026 09:04
|
Some linked issues are invalid. Please update the issue links:\nIssue # in is not found or invalid (HTTP }404).\n |
4 of 16 tasks
|
Some linked issues are invalid. Please update the issue links:\nIssue # in is not found or invalid (HTTP }404).\n |
1 similar comment
|
Some linked issues are invalid. Please update the issue links:\nIssue # in is not found or invalid (HTTP }404).\n |
|
vivek-devtron
approved these changes
Sep 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Fixes https://github.com/devtron-labs/sprint-tasks/issues/2974
The Devtron Apps list, filtered by App Status → Hibernating, returned only a handful of applications and reported that handful as the total, so no further pages were offered — while the CSV export of the same data showed many more hibernating applications.
Root cause
AppListingServiceImpl.FetchAppsByEnvironmentV2special-cased theHIBERNATINGfilter. WheneverHIBERNATINGwas among the selected statuses, the entireAppStatuseslist was blanked before the repository filter was built:So the SQL that actually ran carried no status predicate at all:
SELECT DISTINCT a.id ... WHERE a.active AND a.app_type = 0 <other filters> LIMIT ? OFFSET ?count(distinct a.id)over that same status-lessWHEREThe status filter was then re-applied in memory, after pagination, to the single page that came back, and the total count was overwritten with the size of the surviving slice:
Hence the filter only ever saw the hibernating apps that happened to land on the requested page of the unfiltered listing.
Why the filter belongs in SQL
The premise of the workaround — "AppStatus is available in Db for only ArgoApps" — does not hold for
HIBERNATING:app_status.status.appStatus.UpdateStatusWithAppIdEnvIdnormalisesSuspended/Hibernatedto"HIBERNATING"on write;AppService.ComputeAppstatus→GetHibernationStatuswrites it for GitOps pipelines. Present since Jun 2024 — ten months before this workaround was added in Apr 2025.container.AppStatuscomes fromaps.status as app_statusinGetQueryForAppEnvContainers. The in-memory comparison and the SQL predicateaps.status IN (?)match identical data — the only difference is that one runs beforeLIMIT/OFFSETand the other after. Per-row semantics are therefore unchanged by this PR; only which rows and what count reach the client.updateAppStatusForHelmTypePipelinesis commented out inFetchAppsByEnvironmentV2(removed for slowness), is areturn nilstub in OSS, and is additionally gated behindFETCH_HELM_PIPELINE_APP_STATUS(defaultfalse).The change
Pure deletion — 11 insertions, 31 deletions in one file.
buildAppListingWhereConditionalready emitsand aps.status IN (?)for any status list, and already handles theNOT DEPLOYEDcombination, so nothing replaces the removed code:fetchAppListingRequest.AppStatusesappSize = len(filteredContainers)overrideisFilteredOnHibernatingStatushelper and its importTODO (helm pipelines)note in place of the removed commentNo migration, no config change, no API contract change.
Also fixed, as collateral
Combination filters were broken by the same blanking:
NOT DEPLOYEDSQL branch, and"NOT DEPLOYED"is never a storedaps.status, so the in-memory pass silently dropped every not-deployed app.The reported count also changed units: SQL returns
count(distinct a.id)(apps) whilelen(filteredContainers)counted app-env rows, so an app hibernating in two environments contributed 2.Known gap — deliberately not addressed here
Helm-type (non-GitOps) CD pipelines never get an
app_statusrow, so a hibernated helm-pipeline app cannot be matched by this filter. This is pre-existing, not a regression: the in-memory pass read the same empty column, so those apps matched neither before nor after. Measured on the reporting environment, this cohort is a small fraction of hibernated app-environments; the overwhelming majority are GitOps pipelines and are covered by this fix.The correct fix is to persist helm-pipeline status into
app_statusfrom the status-sync worker — after which the SQL predicate covers them for free — rather than fanning out live status calls during a list request, which is whatupdateAppStatusForHelmTypePipelinesdid and why it was removed from this path. Recorded as aTODOin the code; needs a separate ticket.Related PRs
All four carry the identical change.
devtronanddevtron-enterpriseare a hard fork at the same module path, and the fix is needed on bothmainandhotfix-v0.46.0, so merging only some of these leaves the rest broken:mainhotfix-v0.46.0mainhotfix-v0.46.0Supersedes the earlier agent-authored drafts devtron-labs/devtron-enterprise#3418 and #7048, which took a different approach (an unpaginated fetch capped at 100k rows plus live per-pipeline status calls). Those are closed.
How Has This Been Tested?
go build ./pkg/app/... ./internal/sql/repository/... ./api/restHandler/app/appList/...passes on the enterprisehotfix-v0.46.0branch. No runtime test has been run — there is no existing test harness aroundFetchAppsByEnvironmentV2. Correctness rests on the code trace and on queryingapp_statusdirectly in the affected environment, so please treat the QA list as required rather than optional.sql SELECT count(DISTINCT a.id) FROM app a LEFT JOIN pipeline p ON a.id = p.app_id AND p.deleted = false LEFT JOIN app_status aps ON aps.app_id = a.id AND p.environment_id = aps.env_id WHERE a.active = true AND a.app_type = 0 AND aps.status IN ('HIBERNATING');appNameSort,lastDeployed), ascending and descending.Checklist:
Does this PR introduce a user-facing change?
🤖 Generated with Claude Code