adam-p/markdown-here · error · Error
HTTP error status: ${response.status}
Error message
HTTP error status: ${response.status} What it means
getLocalFile(url, dataType, callback) wraps fetch() to read extension-bundled local resources and rejects any non-2xx response by throwing `HTTP error status: <status>` when response.ok is false. The function is documented as expecting local files that 'are not expected to fail'; a non-OK status is treated as an exceptional condition rather than a recoverable return value. Because the throw happens inside the fetch .then chain and getLocalFile does not return the promise, it surfaces downstream as the wrapped rejection in error [3].
Source
Thrown at src/common/utils.js:301
return url;
}
return chrome.runtime.getURL(url);
}
// Makes an asynchronous XHR request for a local file (basically a thin wrapper).
// `dataType` must be one of 'text', 'json', or 'base64'.
// `callback` will be called with the response value, of a type depending on `dataType`.
// Errors are not expected for local files, and will result in an exception being thrown asynchronously.
// TODO: Return a promise instead of using a callback. This will allow returning an error
// properly, and then this can be used in options.js when checking for the existence of
// the test file.
function getLocalFile(url, dataType, callback) {
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error status: ${response.status}`);
}
switch (dataType) {
case 'text':
return response.text();
case 'json':
return response.json();
case 'base64':
return response.blob();
default:
throw new Error(`Unknown dataType: ${dataType}`);
}
})
.then(data => {
switch (dataType) {
case 'text':
case 'json':
callback(data);View on GitHub (pinned to e00d005299)
Solutions
- Verify the url exists at the exact path passed and log chrome.runtime.getURL(url) to confirm the resolved extension URL.
- Add the resource to manifest.json web_accessible_resources (and match the right extension/extension_ids) if it is fetched from a web context.
- Correct a relative path by passing it through the project's getURL()/chrome.runtime.getURL() helper first.
- If the file may legitimately be absent (e.g. the test-file existence check noted in the TODO), refactor to return the promise so the caller can branch on status instead of throwing.
Example fix
// before
getLocalFile('defaults.json', 'json', cb); // 404 → throws HTTP error status: 404
// after — ensure correct extension-relative URL and manifest entry
getLocalFile(chrome.runtime.getURL('defaults.json'), 'json', cb);
// manifest.json:
// "web_accessible_resources": [{ "resources": ["defaults.json"], "matches": ["<all_urls>"] }] Defensive patterns
Strategy: try-catch
Validate before calling
// Best-effort pre-flight: resolve the extension URL and confirm it is in
// web_accessible_resources before calling getLocalFile.
function resolveLocalUrl(rawUrl) {
const fullUrl = (typeof chrome !== 'undefined' && chrome.runtime)
? chrome.runtime.getURL(rawUrl)
: rawUrl;
return fullUrl;
}
// Note: a 200 cannot be fully guaranteed without fetching; pair with try-catch. Try / catch
// getLocalFile surfaces failures as an unhandled rejection, not via callback,
// so wrap it in a promise you control.
function getLocalFileP(url, dataType) {
return new Promise((resolve, reject) => {
getLocalFile(url, dataType, resolve);
// rejection path: attach a window-level unhandledrejection listener, or
// refactor getLocalFile to return its promise (preferred).
});
}
// Preferred: refactor getLocalFile to `return fetch(url).then(...)` and let the
// caller do `.catch(err => { if (/HTTP error status: (\d+)/.test(err.message)) ... })`. Prevention
- Always pass extension resources through chrome.runtime.getURL before fetching.
- Declare every fetched asset in manifest.json web_accessible_resources.
- Log the resolved URL at the call site during development to catch path/typos.
- Treat a missing local file as a real error path — the function's own comment admits the TODO to return a promise so callers can branch.
When it happens
Trigger: fetch() resolves with a 404/403/500 (etc.) for the given url — most commonly a file path that does not exist, a file not listed in the extension manifest's web_accessible_resources, or a URL resolved against the wrong base. Also a relative url that was not converted with chrome.runtime.getURL before being passed in.
Common situations: Asset was renamed or moved but the caller still requests the old path; new resource added but not declared in manifest.json web_accessible_resources (causing 404/forbidden in extension context); path typos; deploying to a context where chrome.runtime.getURL was not applied so the URL resolves against the document origin instead of the extension.
Related errors
AI-assisted analysis of adam-p/markdown-here@e00d005299 (2026-08-13).
Data as JSON: /api/errors/7ba6f5bffa329b9c.
Report an issue: GitHub.