Skip to content

fix(sources): fallback resolve when callback is never called#2407

Open
soifou wants to merge 2 commits intomainfrom
fix/source-resolve
Open

fix(sources): fallback resolve when callback is never called#2407
soifou wants to merge 2 commits intomainfrom
fix/source-resolve

Conversation

@soifou
Copy link
Collaborator

@soifou soifou commented Feb 20, 2026

Some community sources override source:resolve but may never call the callback, e.g. they check an option that ends up being nil and causes the async task to hang indefinitely (since it's waiting on a callback that will never come):

function source:resolve(item, callback)
  if self.opts.resolve then -- this may be nil
    self.opts.resolve(item, callback) -- callback never called
  end
end

The fix detects this by checking if the callback was invoked synchronously after resolve returns. If not, and there’s no return value indicating async work, we fall back to resolving with the original item.

I believe returning the original item is a safer option, as it avoids indefinite hangs without requiring to strictly follow the resolve contract.

Some community sources override `source:resolve` but may never call the
callback, e.g. they check an option that ends up being nil and causes
the async task to hang indefinitely (since it's waiting on a callback
that will never come):

```lua
function source:resolve(item, callback)
  if self.opts.resolve then -- this may be nil
    self.opts.resolve(item, callback) -- callback never called
  end
end
```

The fix detects this by checking if the callback was invoked
synchronously after resolve returns. If not, and there’s no return value
indicating async work, we fall back to resolving with the original item.

I believe returning the original item is a safer option, as it avoids
indefinite hangs without requiring to strictly follow the resolve
contract.
@saghen
Copy link
Owner

saghen commented Mar 10, 2026

I'd like to avoid patching bugs in sources in blink.cmp itself. I think the issue might be that there's no feedback that the plugin has a bug in it. Perhaps we could have a timeout of 30s and throw an error if the callback isn't called?

@soifou
Copy link
Collaborator Author

soifou commented Mar 11, 2026

Good point about the timeout! I added it alongside the original sync check for full coverage, but kept fallback + warning instead of throwing an error (feels safer for UX).

30s for timeout seem long I set it to 3s instead but feel free to adapt if I miss a case.

The main goal of this PR is to avoid deadlocks. If the callback never fires, the resolve task hangs forever and causes weird issues like misplaced documentation window (detected with faulty source while fixing window artifacts in the other PR).

The warnings explicitly name the buggy source so users don't file blink.cmp issues when it's actually a community source problem, and the authors now get proper feedback while testing their sources.

Thoughts?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants