nodejs/node · error · RuntimeError
%s cannot provide access to the source
Error message
%s cannot provide access to the source
What it means
BaseLoader.get_source checks the class attribute has_source_access; when it is False the loader cannot expose raw template source and get_source raises RuntimeError naming the loader class. In this codebase ModuleLoader sets has_source_access = False (loaders.py:434) because it serves precompiled bytecode modules, not source.
Source
Thrown at tools/inspector_protocol/jinja2/loaders.py:89
"""Get the template source, filename and reload helper for a template.
It's passed the environment and template name and has to return a
tuple in the form ``(source, filename, uptodate)`` or raise a
`TemplateNotFound` error if it can't locate the template.
The source part of the returned tuple must be the source of the
template as unicode string or a ASCII bytestring. The filename should
be the name of the file on the filesystem if it was loaded from there,
otherwise `None`. The filename is used by python for the tracebacks
if no loader extension is used.
The last item in the tuple is the `uptodate` function. If auto
reloading is enabled it's always called to check if the template
changed. No arguments are passed so the function must store the
old state somewhere (for example in a closure). If it returns `False`
the template will be reloaded.
"""
if not self.has_source_access:
raise RuntimeError('%s cannot provide access to the source' %
self.__class__.__name__)
raise TemplateNotFound(template)
def list_templates(self):
"""Iterates over all templates. If the loader does not support that
it should raise a :exc:`TypeError` which is the default behavior.
"""
raise TypeError('this loader cannot iterate over all templates')
@internalcode
def load(self, environment, name, globals=None):
"""Loads a template. This method looks up the template in the cache
or loads one by calling :meth:`get_source`. Subclasses should not
override this method as loaders working on collections of other
loaders (such as :class:`PrefixLoader` or :class:`ChoiceLoader`)
will not call this method but `get_source` directly.
"""
code = NoneView on GitHub (pinned to 1b2de5e052)
Solutions
- Do not call get_source on loaders where has_source_access is False; use load() to obtain a compiled Template instead.
- Provide a source-capable loader (e.g. FileSystemLoader) alongside ModuleLoader via ChoiceLoader if source access is required.
- Check loader.has_source_access before invoking get_source.
Example fix
# before
loader = ModuleLoader('/compiled')
src, fn, uptodate = loader.get_source(env, name) # RuntimeError
# after
loader = ChoiceLoader([
ModuleLoader('/compiled'),
FileSystemLoader('/src'),
])
tmpl = env.get_template(name) # uses load(), not get_source() Defensive patterns
Strategy: type-guard
Validate before calling
def assert_source_access(loader):
if not getattr(loader, 'has_source_access', False):
raise TypeError('loader %s cannot provide source; use load() instead' % type(loader).__name__) Type guard
def loader_has_source(loader) -> bool:
return bool(getattr(loader, 'has_source_access', False)) Try / catch
try:
source, fn, uptodate = loader.get_source(env, name)
except RuntimeError as e:
if 'cannot provide access' in str(e):
tmpl = env.get_template(name) # fall back to load()
else:
raise Prevention
- Check loader.has_source_access before calling get_source.
- Pair ModuleLoader with a source-capable loader via ChoiceLoader when source access is needed.
- Treat ModuleLoader as bytecode-only; never assume source is available.
When it happens
Trigger: Calling loader.get_source(env, name) on a ModuleLoader (or any loader with has_source_access = False), or any code path that expects source — debugging tools, reload checks, or compile_templates introspection — against such a loader.
Common situations: Shipping precompiled templates via ModuleLoader for performance/distribution, then running tooling (debuggers, source-inspection, auto-reload) that assumes source is available.
Related errors
- no loader for this environment specified
- none of the templates given were found: %s
- {template}
- this loader cannot iterate over all templates
- The environment was not created with async mode enabled.
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/79ec98cba85cf445.
Report an issue: GitHub.