vxcontrol/pentagi · warning

ErrTermlogsInvalidRequest

ErrTermlogsInvalidRequest

Error message

group field not found

What it means

GetTermlogs supports grouped terminal-log queries. The `group` query parameter must name a field in termlogsSQLMappers; otherwise the handler responds with ErrTermlogsInvalidRequest before executing the aggregation.

Source

Thrown at backend/pkg/server/services/termlogs.go:99

		}
	} else if slices.Contains(privs, "termlogs.view") {
		scope = func(db *gorm.DB) *gorm.DB {
			return db.
				Joins("INNER JOIN flows f ON f.id = 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("termlogs", termlogsSQLMappers)

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

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

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

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

View on GitHub (pinned to ea665308ba)

Solutions

  1. Use a group value defined in termlogsSQLMappers in backend/pkg/server/services/termlogs.go.
  2. Remove the group parameter to get the flat listing.
  3. Update the client's group-by options to the supported fields.
  4. Extend termlogsSQLMappers if the field must become groupable.

Example fix

// before
GET /api/v1/termlogs?group=container_name
// after
GET /api/v1/termlogs?group=type
Defensive patterns

Strategy: validation

Validate before calling

const TERMLOGS_GROUP_FIELDS = ['type', 'created_at']; // keys of termlogsSQLMappers
if (group && !TERMLOGS_GROUP_FIELDS.includes(group)) {
  throw new Error(`invalid group field for termlogs: ${group}`);
}

Type guard

function isValidTermlogGroup(g) {
  return typeof g === 'string' && TERMLOGS_GROUP_FIELDS.includes(g);
}

Try / catch

try {
  return await api.getTermlogs({ group });
} catch (e) {
  if (e.code === 'ErrTermlogsInvalidRequest' && e.message === 'group field not found') {
    return await api.getTermlogs({});
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /termlogs?group=<field> where <field> is not a key of termlogsSQLMappers, e.g. grouping by a container or command field that is not mapped as groupable.

Common situations: Terminal-log viewers offering a group-by dropdown built from table columns rather than the mapper allow-list; clients reusing group values from other entities; older API versions exposing more group fields than the current mappers.

Related errors


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