ovity/octotree · error · Error
promisify: fn does not have ${method} method
Error message
promisify: fn does not have ${method} method What it means
promisify(fn, method) in core.storage.js wraps a callback-style storage backend (chrome.storage-based class) into a Promise API by checking that fn has the given method before wrapping it. If the passed object lacks the method, it throws 'promisify: fn does not have <method> method' synchronously from the storage controller constructor.
Source
Thrown at src/core.storage.js:156
'If the local storage for this domain is full, please clean it up and try again.';
console.error(msg, e);
}
resolve();
}
});
}
_removeLocal (key) {
return new Promise((resolve) => {
localStorage.removeItem(key);
resolve();
});
}
}
function promisify(fn, method) {
if (typeof fn[method] !== 'function') {
throw new Error(`promisify: fn does not have ${method} method`);
}
return function(...args) {
return new Promise(function(resolve, reject) {
fn[method](...args, function(res) {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
} else {
resolve(res);
}
});
});
};
}
window.extStore = new ExtStore(STORE, DEFAULTS)
View on GitHub (pinned to 470747c700)
Solutions
- Implement the missing method on the storage object passed to the constructor (match the exact name in the error message)
- Pass the correct storage backend class instance/dependency wiring instead of a partial or mock object
- Check for typos or renamed methods between your backend and what promisify expects (get, set, remove, etc.)
- Pin/align your custom backend with the version of Octotree in use, adding any newly required methods
Example fix
// before
const store = { get(key, cb) { /* ... */ } };
new Storage(store); // throws: promisify: fn does not have set method
// after
const store = {
get(key, cb) { /* ... */ },
set(obj, cb) { /* ... */ },
remove(key, cb) { /* ... */ }
};
new Storage(store); Defensive patterns
Strategy: validation
Validate before calling
const REQUIRED = ['get', 'set', 'remove'];
const missing = REQUIRED.filter((m) => typeof store[m] !== 'function');
if (missing.length) {
throw new Error(`storage backend missing methods: ${missing.join(', ')}`);
} Type guard
function isValidStorageBackend(fn) {
return typeof fn === 'object' && fn !== null &&
['get', 'set', 'remove'].every((m) => typeof fn[m] === 'function');
} Try / catch
let storage;
try {
storage = new Storage(backend);
} catch (err) {
if (/^promisify: fn does not have /.test(err.message)) {
console.error('Storage backend is missing a required method:', err.message);
storage = new Storage(chromeStorageFallback);
} else { throw err; }
} Prevention
- Validate the backend object implements every method the storage class promisifies before constructing it
- Keep custom storage backends (tests, Firefox port) in sync with the method set expected by core.storage.js
- Check exact method names in the error message — they reveal which dependency is incomplete
- Watch for Octotree updates that add new promisified storage methods
When it happens
Trigger: The storage controller constructor calls promisify(fn, 'get'|'set'|'remove'|...) with a backend object that is missing one of the required methods — e.g. a custom/partial storage implementation, a wrongly injected dependency, or a renamed method after a chrome.* API or version change.
Common situations: Implementing a custom storage backend (e.g. for Firefox or tests) that omits a required method like remove() or get(); passing the wrong object (undefined/mock) as the storage dependency; an Octotree version bump adding a new promisified method that custom backends don't provide.
AI-assisted analysis of ovity/octotree@470747c700 (2026-08-31).
Data as JSON: /api/errors/c0f2c0fb831da1e2.
Report an issue: GitHub.