Skip to content

SkillRunner daily_report GitHub proxy 403s at runtime #411

@eanzhao

Description

@eanzhao

Problem

A scheduled daily_report SkillRunner can be created successfully, but at execution time every GitHub request through NyxID api-github proxy returns 403. On retry, the model also emitted one malformed nyxid_proxy call with slug=api-github and no path.

This is separate from the Lark reaction permission noise and from the Lark open_id cross app delivery error.

Evidence

From aevatar-console-backend-75fd899df8-s6mp7_aevatar-console-backend.log:

  • First run produced three GitHub tool calls, all 403:
    • GET api-github /search/commits?q=author:eanzhao+author-date:>=2026-04-24T05:30:47Z -> 403
    • GET api-github /search/issues?q=author:eanzhao+updated:>=2026-04-24T05:30:47Z -> 403
    • GET api-github /search/issues?q=commenter:eanzhao+updated:>=2026-04-24T05:30:47Z -> 403
  • Retry produced:
    • [nyxid_proxy] Missing path. slug=api-github, raw={\"slug\":\"api-github\",\"method\":\"GET\"}
    • GET api-github /users/eanzhao/events/public -> 403
    • GET api-github /users/eanzhao -> 403

Relevant code path

  • AgentBuilderTemplates.TryBuildDailyReportSpec tells the runner to use nyxid_proxy with service slug api-github and suggests the search endpoints.
  • AgentBuilderTool.CreateDailyReportAgentAsync verifies that GitHub appears connected, resolves required service ids, then creates a new NyxID API key.
  • AgentBuilderTool.BuildCreateApiKeyPayload only sets scopes=proxy, platform=generic, and allowed_service_ids.
  • SkillRunnerGAgent.BuildExecutionMetadata passes the generated API key as NyxIdAccessToken during scheduled execution.
  • NyxIdApiKeysTool exposes a bind action using /api/v1/api-keys/{keyId}/bindings, but the daily report builder does not bind the generated key to the user's GitHub credential, and it does not preflight GitHub proxy access with the generated key.
  • NyxIdApiClient.SendAsync returns the proxy response body to the tool result, but the server log only records URL/status, so the log does not show the actual NyxID/GitHub 403 body.

Current hypothesis

Most likely the generated agent API key is allowed to use the api-github service but does not have a usable bound GitHub credential, or the stored GitHub OAuth credential is expired/insufficient. Either way, agent creation currently accepts a daily_report agent that cannot fetch GitHub data at runtime.

I could not verify the NyxID backend behavior locally because the sibling NyxID repository was not present in the workspace.

Expected behavior

A daily_report agent should not be enabled unless the generated runtime API key can actually proxy GitHub requests needed by the report. If GitHub proxy access later fails with 401/403, the run should fail with an actionable credential/proxy error instead of letting the LLM continue with empty or degraded data.

Suggested fixes

  1. During daily report creation, after creating the agent API key, either bind it to the user's GitHub credential if NyxID requires bindings, or preflight a safe GitHub endpoint using the generated key, such as /user or /rate_limit, before enabling the agent.
  2. Surface all-required-GitHub-tool-calls-failed as a SkillRunner execution failure with a clear LastError.
  3. Add sanitized diagnostic logging for NyxID proxy error bodies, especially 401/403, so we can distinguish missing binding, expired OAuth, missing GitHub scope, and GitHub rate/permission problems.
  4. Tighten the daily report GitHub access path, for example with a typed GitHub activity tool or stricter validation, so malformed nyxid_proxy calls without path do not become noisy warning-level runtime logs.

Out of scope

  • Lark reaction permission errors can be ignored for this issue.
  • Lark message delivery open_id cross app is tracked separately by the Lark receive-id fix path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions