vxcontrol/pentagi · error

Containers.InvalidRequest

Containers.InvalidRequest

Error message

group field not found

What it means

GetContainers checks the `group` query parameter against containersSQLMappers before running the grouped container count query. A value not in the whitelist is rejected with Containers.InvalidRequest and message 'group field not found', preventing unvalidated input in the GROUP BY SQL.

Solutions

  1. Use an exact key from containersSQLMappers (backend/pkg/server/services/containers.go)
  2. Verify allowed values in the Swagger docs for GET /containers
  3. Remove the group parameter for ungrouped listing
  4. Add the desired field to containersSQLMappers via a code change

Example fix

// before
GET /api/v1/containers?group=container_status
// after
GET /api/v1/containers?group=status  (valid mapper key)
Defensive patterns

Strategy: validation

Validate before calling

const containersGroups = ["type","status","flow","node"];
function assertValidGroup(g?: string) {
  if (g && !containersGroups.includes(g)) {
    throw new Error(`invalid containers group: ${g}`);
  }
}
assertValidGroup(group);

Type guard

function isContainersGroup(g: string): g is typeof containersGroups[number] {
  return (containersGroups as string[]).includes(g);
}

Try / catch

try {
  return await api.get('/containers', { params: { group } });
} catch (e) {
  if (e.response?.data?.code === 'Containers.InvalidRequest') {
    // retry without grouping
    return await api.get('/containers');
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /containers?group=<field> where <field> is absent from containersSQLMappers — e.g. group=container_image when the mapper exposes group=image.

Common situations: Dashboard code grouping by a field renamed in a backend update; using fields valid on the flow-scoped variant that were removed from the shared mapper; scripts written against an older API version.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/97f1968823ea7022. Report an issue: GitHub.

Appendix: source

Thrown at backend/pkg/server/services/containers.go:101

		}
	} else if slices.Contains(privs, "containers.view") {
		scope = func(db *gorm.DB) *gorm.DB {
			return db.
				Joins("INNER JOIN flows f ON f.id = containers.flow_id").
				Where("f.user_id = ?", uid)
		}
	} else {
		logger.FromContext(c).Errorf("error filtering user role permissions: permission not found")
		response.Error(c, response.ErrNotPermitted, nil)
		return
	}

	query.Init("containers", containersSQLMappers)

	if query.Group != "" {
		if _, ok := containersSQLMappers[query.Group]; !ok {
			logger.FromContext(c).Errorf("error finding containers grouped: group field not found")
			response.Error(c, response.ErrContainersInvalidRequest, errors.New("group field not found"))
			return
		}

		var respGrouped containersGrouped
		if respGrouped.Total, err = query.QueryGrouped(s.db, &respGrouped.Grouped, scope); err != nil {
			logger.FromContext(c).WithError(err).Errorf("error finding containers grouped")
			response.Error(c, response.ErrInternal, err)
			return
		}

		response.Success(c, http.StatusOK, respGrouped)
		return
	}

	if resp.Total, err = query.Query(s.db, &resp.Containers, scope); err != nil {
		logger.FromContext(c).WithError(err).Errorf("error finding containers")
		response.Error(c, response.ErrInternal, err)
		return

View on GitHub (pinned to ea665308ba)