Skip to content

fix: report whether a runtime is still initializing in ListResources - #9861

Open
nishantmonu51 wants to merge 1 commit into
mainfrom
deny_all
Open

fix: report whether a runtime is still initializing in ListResources#9861
nishantmonu51 wants to merge 1 commit into
mainfrom
deny_all

Conversation

@nishantmonu51

Copy link
Copy Markdown
Collaborator

ListResources returns 200 with an empty list when security policies deny every resource, which is what a deny-by-default project does for users entitled to nothing. Clients read that as "the runtime isn't ready yet" and polled forever behind a spinner that never resolved.

  • Add initializing to ListResourcesResponse, computed from Controller.Initializing() rather than from the returned resources, so it stays meaningful when the response is empty or narrowed by kind/path.
  • Controller.Initializing() latches: once the initial parse and reconcile completes it stays false for the controller's lifetime, so a model refresh or a hidden RefreshTrigger does not make the instance look like it is building again. A started flag set alongside Run's initial enqueue closes the window where every resource is still IDLE and the instance would report "done" before it had begun.
  • useIsInitialBuild and the dashboards refetch interval now key off the flag instead of guessing from an empty list.
  • Render an access-denied page on the canvas and explore embed surfaces, which previously showed a spinner or nothing at all for a denied user. ResolveCanvas now retries network errors only, so a 403 surfaces immediately instead of after five retries.

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

https://claude.ai/code/session_016toijNcMp2pV3UQ2WoZUhc

`ListResources` returns 200 with an empty list when security policies deny
every resource, which is what a deny-by-default project does for users who are
entitled to nothing. The frontend read that as "the runtime isn't ready yet"
and polled forever behind a spinner that never resolved.

Add an `initializing` flag to `ListResourcesResponse`, derived from controller
state rather than the returned resources, so it stays meaningful when every
resource is filtered out. `Controller.Initializing` latches: once the initial
parse and reconcile completes it stays false, so a later model refresh does not
make the instance look like it is building again.

Also surface access-denied errors on the canvas and explore embed surfaces,
which previously rendered nothing at all for a denied user.

Claude-Session: https://claude.ai/code/session_016toijNcMp2pV3UQ2WoZUhc
@nishantmonu51 nishantmonu51 added Type:Bug Something isn't working Size:M Medium change: 100-499 lines labels Sep 4, 2026

@AdityaHegde AdityaHegde left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving with some small nits.
@begelundmuller can you take a look at the reconcile code once?

repeated Resource resources = 1;
string next_page_token = 2;
// True while the instance may still produce more resources, i.e. it has not finished its initial parse and reconcile.
// It is computed before security policies are applied, so it stays meaningful when every resource is denied.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems extremely specific comment for the issue this PR is fixing. May be just the first line at 856 is enough?

return nil, err
}

// Clients can't infer this from the returned resources:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we have a comment on initializing field and on Initializing method, this is redundant.

Comment thread runtime/controller.go
return ctx.Err()
}

// Initializing returns true until the controller has completed its initial parse and reconcile,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this comment block should maybe add some info on how started and initialized are used instead of talking about callers.

if (!resources || resources.length === 0) {
// No data yet (the query errored or hasn't resolved): keep polling so we
// pick up resources once the runtime responds.
if (!resources) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving the initializing check here? Feels like a good place to refetch at MAX_REFETCH_INTERVAL

It will refetch even if one relevant resource is available but IMO it will be good to have all relevant resources parsed before running the rest of the code.

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

Labels

Size:M Medium change: 100-499 lines Type:Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants