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.

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)

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.