neoclide/coc.nvim · error · ResourceNotFoundError
${e instanceof Error ? e.message : String(e)}
Error message
${e instanceof Error ? e.message : String(e)} What it means
For a `coc://document/<uri>` resource backed by a real file (not an open document), the server reads the file from disk with `fs.readFileSync`. Any filesystem failure (ENOENT, EACCES, EISDIR) is wrapped into a `ResourceNotFoundError` with the underlying error message.
Source
Thrown at src/mcp/resources.ts:82
name: 'Document content',
description: 'Text content of an editor document (file URI encoded as parameter).'
}]
}
}
public async read(uri: string): Promise<{ contents: ResourceContent[] }> {
if (uri.startsWith(DOCUMENT_PREFIX)) {
let fileUri = decodeURIComponent(uri.slice(DOCUMENT_PREFIX.length))
let ref = await resolveDocument(fileUri, false)
if (ref.error) throw new ResourceNotFoundError(ref.error)
let text: string
if (ref.doc) {
text = ref.doc.getDocumentContent()
} else {
try {
text = fs.readFileSync(toFsPath(fileUri), 'utf8')
} catch (e) {
throw new ResourceNotFoundError(e instanceof Error ? e.message : String(e))
}
}
return { contents: [{ uri, mimeType: 'text/plain', text }] }
}
switch (uri) {
case 'coc://diagnostics': {
let list = await diagnosticManager.getDiagnosticList()
return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(list, null, 2) }] }
}
case 'coc://services': {
let stats = services.getServiceStats().map(stat => {
let service = services.getService(stat.id)
let init = service?.client?.initializeResult
return {
id: stat.id,
state: stat.state,
languageIds: stat.languageIds,
capabilities: init?.capabilities ?? nullView on GitHub (pinned to 50e974d969)
Solutions
- Check the exact message (ENOENT vs EACCES vs EISDIR) to identify the filesystem problem
- Verify the file exists and is readable at the encoded path
- Re-list resources to refresh URIs after files moved
- Do not wrap the encoded URI again (double-encoding produces a wrong path)
Example fix
// before
await read('coc://document/' + encodeURIComponent('file:///missing.txt')) // double-encoded
// after
await read(URI.file('/missing.txt').toString().replace('file://', 'coc://document/')) Defensive patterns
Strategy: try-catch
Validate before calling
const fileUri = decodeURIComponent(uri.slice('coc://document/'.length))
const stat = fs.existsSync(toFsPath(fileUri)) ? fs.statSync(toFsPath(fileUri)) : null
if (!stat) throw new Error(`File not found: ${fileUri}`)
if (!stat.isFile()) throw new Error(`Not a regular file: ${fileUri}`) Try / catch
try {
const res = await resources.read(uri)
} catch (e) {
if (/ENOENT/.test(e.message)) logger.warn(`File gone: ${uri}`)
else if (/EACCES/.test(e.message)) logger.error(`Permission denied: ${uri}`)
else if (/EISDIR/.test(e.message)) logger.error(`URI points to a directory: ${uri}`)
else throw e
} Prevention
- Check file existence before embedding paths in document resource URIs
- Avoid pointing resources at directories
- Re-check filesystem state after long-running sessions
- Distinguish ENOENT/EACCES/EISDIR in handlers
When it happens
Trigger: `resources.read('coc://document/<file-uri>')` where the file does not exist, lacks read permission, or the URI points to a directory — the readFileSync throws and the message (e.g. 'ENOENT: no such file or directory') becomes the error text.
Common situations: File deleted or moved after being listed as a resource; wrong absolute path in the URI; permission issues when the server runs as a different user; passing a directory instead of a file.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ${ref.error}
- Resource not found: ${uri}
- unable to watch
- Tool name is required
- Tool ${tool.name} already registered
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/0b347d1ff8ba9481.
Report an issue: GitHub.