Skip to content

Recall: setting Session agent filter fails insight generation with huma required-property error #1596

Description

@cderv

agentsview version

agentsview v0.42.0 (commit ff8fb4e, built 2026-09-01T19:48:29Z)

Install method

GitHub release binary (via scoop, r-bucket)

OS / platform

Windows 11 Pro (10.0.26200)

Which agent and version

n/a (unrelated to a specific coding agent's session data)

Which model(s)

n/a

What happened, and what did you expect

On the Recall page, "Generated insights" tab, I set "Session agent" to Claude while leaving the template at "Model and Cost" and generator at "Codex", then clicked Generate. It failed immediately with:

expected required property automated_scope to be present (body.filters: map[agent:claude]); expected required property include_one_shot to be present (body.filters: map[agent:claude]); expected required property timezone to be present (body.filters: map[agent:claude])

I expected the generation to run with just the agent filter applied, the same way it does when "Session agent" is left unset.

Steps to reproduce

  1. Open Recall → Generated insights.
  2. Leave Session scope at "No automated", Template at "Model and Cost".
  3. Set "Session agent" to any agent (e.g. Claude).
  4. Click Generate.
  5. Observe the "Generation error" panel with the message above.

What I'm seeing in the code

I'm not fully sure this is the right read, please correct me if I'm missing something server-side.

insights.svelte.ts builds the filters payload only from the session-agent picker, with nothing else set:

sessionFilters: this.type === "llm_canned" && this.sessionAgent
? { agent: this.sessionAgent }
: undefined,

sessionFilters: this.type === "llm_canned" && this.sessionAgent
  ? { agent: this.sessionAgent }
  : undefined,

On the server, CannedSessionFilters declares timezone, include_one_shot, and automated_scope without omitempty:

type CannedSessionFilters struct {
Timezone string `json:"timezone"`
Machine string `json:"machine,omitempty"`
Agent string `json:"agent,omitempty"`
Termination string `json:"termination,omitempty"`
MinUserMessages int `json:"min_user_messages,omitempty"`
IncludeOneShot bool `json:"include_one_shot"`
AutomatedScope string `json:"automated_scope"`
ActiveSince string `json:"active_since,omitempty"`
}

type CannedSessionFilters struct {
	Timezone        string `json:"timezone"`
	Machine         string `json:"machine,omitempty"`
	Agent           string `json:"agent,omitempty"`
	Termination     string `json:"termination,omitempty"`
	MinUserMessages int    `json:"min_user_messages,omitempty"`
	IncludeOneShot  bool   `json:"include_one_shot"`
	AutomatedScope  string `json:"automated_scope"`
	ActiveSince     string `json:"active_since,omitempty"`
}

It looks like huma turns those three fields into required JSON-schema properties and rejects the request body before the handler runs, since the error text matches huma's schema-validation format rather than an application-level message.

There's also a normalizeCannedSessionFilters helper that looks like it was written to backfill exactly these fields from the top-level request when filters is present but incomplete:

func normalizeCannedSessionFilters(
req generateInsightRequest,
) (insight.CannedSessionFilters, string, bool) {
requestTimezone := strings.TrimSpace(req.Timezone)
filters := insight.CannedSessionFilters{
Timezone: requestTimezone,
AutomatedScope: req.AutomatedScope,
}
if req.Filters != nil {
filters = *req.Filters
}
filters.Timezone = strings.TrimSpace(filters.Timezone)
if filters.Timezone == "" {
filters.Timezone = requestTimezone
}
if filters.Timezone == "" {
filters.Timezone = "UTC"
}
if _, err := time.LoadLocation(filters.Timezone); err != nil {
return insight.CannedSessionFilters{},
"invalid timezone: " + filters.Timezone, false
}

If that's right, the huma-level required-property check on CannedSessionFilters happens earlier than that normalization and never lets a partial filters object reach it, which would explain why sending just {agent: ...} fails while omitting filters entirely (and using the top-level agent field instead) works fine.

Sample session file or snippet

n/a — not a parse/render bug, this is a request payload rejected before it reaches any session data.

Checklist

  • I searched existing issues
  • I removed secrets and private data from any attached session files

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions